Bump to 2.10.4

This commit is contained in:
ppasq committed 2020-07-02 11:29:32 +02:00
1 parent aedadb16f7
commit f67a4980ef
436 files changed
+24645 -32623

No files matched your search

+166
View File
@@ -0,0 +1,166 @@
COMPOSE_PROJECT_NAME=haitidata
BACKUPS_VOLUME_DRIVER=local
DOCKER_HOST_IP=
DOCKER_ENV=production
# See https://github.com/geosolutions-it/geonode-generic/issues/28
# to see why we force API version to 1.24
DOCKER_API_VERSION="1.24"
C_FORCE_ROOT=1
IS_CELERY=false
IS_FIRST_START=true
FORCE_REINIT=false
SITEURL=http://localhost/
ALLOWED_HOSTS=['django',]
GEONODE_INSTANCE_NAME=geonode
DJANGO_SETTINGS_MODULE=haitidata.settings
UWSGI_CMD=uwsgi --ini /usr/src/haitidata/uwsgi.ini
# #################
# backend
# #################
GEONODE_DATABASE=geonode
GEONODE_DATABASE_PASSWORD=geonode
GEONODE_GEODATABASE=geonode_data
GEONODE_GEODATABASE_PASSWORD=geonode_data
DATABASE_URL=postgres://geonode:geonode@db:5432/geonode
GEODATABASE_URL=postgis://geonode:geonode@db:5432/geonode_data
DEFAULT_BACKEND_DATASTORE=datastore
BROKER_URL=amqp://guest:guest@rabbitmq:5672/
# #################
# geoserver
# #################
GEOSERVER_WEB_UI_LOCATION=http://localhost/geoserver/
GEOSERVER_PUBLIC_LOCATION=http://localhost/geoserver/
GEOSERVER_LOCATION=http://geoserver:8080/geoserver/
GEOSERVER_ADMIN_PASSWORD=geoserver
OGC_REQUEST_TIMEOUT=30
OGC_REQUEST_MAX_RETRIES=1
OGC_REQUEST_BACKOFF_FACTOR=0.3
OGC_REQUEST_POOL_MAXSIZE=10
OGC_REQUEST_POOL_CONNECTIONS=10
# Java Options & Memory
GEOSERVER_JAVA_OPTS=-Djava.awt.headless=true -Xms2G -Xmx4G -XX:PerfDataSamplingInterval=500 -XX:SoftRefLRUPolicyMSPerMB=36000 -XX:-UseGCOverheadLimit -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:ParallelGCThreads=4 -Dfile.encoding=UTF8 -Duser.timezone=GMT -Djavax.servlet.request.encoding=UTF-8 -Djavax.servlet.response.encoding=UTF-8 -Duser.timezone=GMT -Dorg.geotools.shapefile.datetime=true -DGEOSERVER_CSRF_DISABLED=true
# Data Uploader
DEFAULT_BACKEND_UPLOADER=geonode.importer
TIME_ENABLED=True
MOSAIC_ENABLED=False
# #################
# nginx
# HTTPD Server
# #################
# IP or domain name and port where the server can be reached on HTTP (leave HOST empty if you want to use HTTPS only)
GEONODE_LB_HOST_IP=localhost
HTTP_HOST=localhost
# port where the server can be reached on HTTP
GEONODE_LB_PORT=80
HTTP_PORT=80
# IP or domain name and port where the server can be reached on HTTPS (leave HOST empty if you want to use HTTP only)
# HTTPS_HOST=localhost
# port where the server can be reached on HTTPS
# GEONODE_LB_PORT=443
# HTTPS_PORT=443
# Let's Encrypt certificates for https encryption. You must have a domain name as HTTPS_HOST (doesn't work
# with an ip) and it must be reachable from the outside. This can be one of the following :
# disabled : we do not get a certificate at all (a placeholder certificate will be used)
# staging : we get staging certificates (are invalid, but allow to test the process completely and have much higher limit rates)
# production : we get a normal certificate (default)
LETSENCRYPT_MODE=disabled
# LETSENCRYPT_MODE=staging
# LETSENCRYPT_MODE=production
RESOLVER=127.0.0.11
# #################
# Security
# #################
# Admin Settings
ADMIN_PASSWORD=admin
ADMIN_EMAIL=admin@localhost
# EMAIL Notifications
EMAIL_ENABLE=False
DJANGO_EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
DJANGO_EMAIL_HOST=localhost
DJANGO_EMAIL_PORT=25
DJANGO_EMAIL_HOST_USER=
DJANGO_EMAIL_HOST_PASSWORD=
DJANGO_EMAIL_USE_TLS=False
DEFAULT_FROM_EMAIL='GeoNode <no-reply@geonode.org>'
# Session/Access Control
LOCKDOWN_GEONODE=False
CORS_ORIGIN_ALLOW_ALL=True
SESSION_EXPIRED_CONTROL_ENABLED=True
DEFAULT_ANONYMOUS_VIEW_PERMISSION=True
DEFAULT_ANONYMOUS_DOWNLOAD_PERMISSION=True
# Users Registration
ACCOUNT_OPEN_SIGNUP=True
ACCOUNT_EMAIL_REQUIRED=True
ACCOUNT_APPROVAL_REQUIRED=False
ACCOUNT_CONFIRM_EMAIL_ON_GET=False
ACCOUNT_EMAIL_VERIFICATION='optional'
ACCOUNT_EMAIL_CONFIRMATION_EMAIL=False
ACCOUNT_EMAIL_CONFIRMATION_REQUIRED=False
# OAuth2
OAUTH2_API_KEY=
OAUTH2_CLIENT_ID=Jrchz2oPY3akmzndmgUTYrs9gczlgoV20YPSvqaV
OAUTH2_CLIENT_SECRET=rCnp5txobUo83EpQEblM8fVj3QT5zb5qRfxNsuPzCqZaiRyIoxM4jdgMiZKFfePBHYXCLd7B8NlkfDBY9HKeIQPcy5Cp08KQNpRHQbjpLItDHv12GvkSeXp6OxaUETv3
# GeoNode APIs
API_LOCKDOWN=False
TASTYPIE_APIKEY=
# #################
# Production and
# Monitoring
# #################
DEBUG=False
SECRET_KEY='myv-y4#7j-d*p-__@j#*3z@!y24fz8%^z2v6atuy4bo9vqr1_a'
STATIC_ROOT=/mnt/volumes/statics/static/
MEDIA_ROOT=/mnt/volumes/statics/uploaded/
GEOIP_PATH=/mnt/volumes/statics/geoip.db
CACHE_BUSTING_STATIC_ENABLED=False
CACHE_BUSTING_MEDIA_ENABLED=False
MAX_DOCUMENT_SIZE=2
CLIENT_RESULTS_LIMIT=5
API_LIMIT_PER_PAGE=1000
ALLOWED_DOCUMENT_TYPES=['doc', 'docx', 'gif', 'jpg', 'jpeg', 'ods', 'odt', 'odp', 'pdf', 'png','ppt', 'pptx', 'rar', 'sld', 'tif', 'tiff', 'txt', 'xls', 'xlsx', 'xml', 'zip', 'gz', 'qml']
# GIS Client
GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY=mapstore
MAPBOX_ACCESS_TOKEN=
BING_API_KEY=
GOOGLE_API_KEY=
# Monitoring
MONITORING_ENABLED=True
MONITORING_DATA_TTL=365
USER_ANALYTICS_ENABLED=True
USER_ANALYTICS_GZIP=False
MONITORING_SERVICE_NAME=local-geonode
MONITORING_HOST_NAME=geonode
# Other Options/Contribs
MODIFY_TOPICCATEGORY=True
AVATAR_GRAVATAR_SSL=True
EXIF_ENABLED=False
CREATE_LAYER=False
FAVORITE_ENABLED=False
+10 -9
View File
@@ -1,6 +1,3 @@
.DS_Store
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
@@ -10,7 +7,7 @@ __pycache__/
# Distribution / packaging
.Python
env/
# env/
build/
develop-eggs/
dist/
@@ -46,12 +43,9 @@ nosetests.xml
coverage.xml
*,cover
# Translations
#*.mo
*.pot
# Django stuff:
*.log
celerybeat-schedule.*
# Sphinx documentation
docs/_build/
@@ -61,7 +55,14 @@ target/
# Downstream Project
downloaded/
geoserver/
uploaded/
static_root/
development.db
development.db-journal
local_settings.py
.idea/
/.vscode/settings.json
.DS_Store
+58
View File
@@ -0,0 +1,58 @@
FROM python:2.7.16-stretch
MAINTAINER GeoNode development team
RUN mkdir -p /usr/src/haitidata
# This section is borrowed from the official Django image but adds GDAL and others
RUN apt-get update && apt-get install -y \
gcc \
zip \
gettext \
postgresql-client libpq-dev \
sqlite3 \
python-gdal python-psycopg2 \
python-imaging python-lxml \
python-dev libgdal-dev \
python-ldap \
libmemcached-dev libsasl2-dev zlib1g-dev \
python-pylibmc \
uwsgi uwsgi-plugin-python \
--no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN printf "deb http://archive.debian.org/debian/ jessie main\ndeb-src http://archive.debian.org/debian/ jessie main\ndeb http://security.debian.org jessie/updates main\ndeb-src http://security.debian.org jessie/updates main" > /etc/apt/sources.list
RUN apt-get update && apt-get install -y geoip-bin
# add bower and grunt command
COPY . /usr/src/haitidata/
WORKDIR /usr/src/haitidata
RUN apt-get update && apt-get -y install cron
COPY monitoring-cron /etc/cron.d/monitoring-cron
RUN chmod 0644 /etc/cron.d/monitoring-cron
RUN crontab /etc/cron.d/monitoring-cron
RUN touch /var/log/cron.log
RUN service cron start
COPY wait-for-databases.sh /usr/bin/wait-for-databases
RUN chmod +x /usr/bin/wait-for-databases
RUN chmod +x /usr/src/haitidata/tasks.py \
&& chmod +x /usr/src/haitidata/entrypoint.sh
# Upgrade pip
RUN pip install pip==20.1
# To understand the next section (the need for requirements.txt and setup.py)
# Please read: https://packaging.python.org/requirements/
# fix for known bug in system-wide packages
RUN ln -fs /usr/lib/python2.7/plat-x86_64-linux-gnu/_sysconfigdata*.py /usr/lib/python2.7/
# app-specific requirements
RUN pip install --src /usr/src -r requirements.txt
RUN pip install -e .
# Install pygdal (after requirements for numpy 1.16)
RUN pip install pygdal==$(gdal-config --version).*
ENTRYPOINT service cron restart && /usr/src/haitidata/entrypoint.sh
+29
View File
@@ -0,0 +1,29 @@
up:
# bring up the services
docker-compose up -d
build:
docker-compose build django
docker-compose build celery
sync:
# set up the database tablea
docker-compose run django python manage.py makemigrations --noinput
docker-compose exec django python manage.py migrate account --noinput
docker-compose run django python manage.py migrate --noinput
wait:
sleep 5
logs:
docker-compose logs --follow
down:
docker-compose down
test:
docker-compose run django python manage.py test --failfast
reset: down up wait sync
hardreset: pull build reset
+231
View File
@@ -0,0 +1,231 @@
# Haitidata
GeoNode template project. Generates a django project with GeoNode support.
## Table of Contents
- [Developer Workshop](#developer-Workshop)
- [Create a custom project](#create-a-custom-project)
- [Start your server using Docker](#start-your-server-using-docker)
- [Run the instance in development mode](#run-the-instance-in-development-mode)
- [Run the instance on a public site](#run-the-instance-on-a-public-site)
- [Stop the Docker Images](#stop-the-docker-images)
- [Recommended: Track your changes](#recommended-track-your-changes)
- [Hints: Configuring `requirements.txt`](#hints-configuring-requirementstxt)
- [Hints: Using Ansible](#hints-using-ansible)
- [Configuration](#configuration)
## Developer Workshop
Available at
```bash
http://geonode.org/dev-workshop
```
## Create a custom project
**NOTE**: *You can call your geonode project whatever you like following the naming conventions for python packages (generally lower case with underscores (``_``). In the examples below, replace ``my_geonode`` with whatever you would like to name your project.*
### Using a Python virtual environment
**NOTE**: *Skip this part if you want to run the project using Docker instead*
(see [Start your server using Docker](#start-your-server-using-docker))
To setup your project using a local python virtual environment, follow these instructions:
1. Prepare the Environment
```bash
git clone https://github.com/GeoNode/geonode-project.git -b <your_branch>
mkvirtualenv my_geonode
pip install Django==1.11.29
django-admin startproject --template=./geonode-project -e py,sh,md,rst,json,yml,ini,env,sample -n monitoring-cron -n Dockerfile my_geonode
cd my_geonode
```
2. Setup the Python Dependencies
**NOTE**: *Important: modify your `requirements.txt` file, by adding the `GeoNode` branch before continue!*
(see [Hints: Configuring `requirements.txt`](#hints-configuring-requirementstxt))
```bash
pip install -r requirements.txt
pip install -e .
# Install GDAL Utilities for Python
pip install pygdal=="`gdal-config --version`.*"
# Using the Default Settings
DJANGO_SETTINGS_MODULE=my_geonode.settings paver reset
DJANGO_SETTINGS_MODULE=my_geonode.settings paver setup
DJANGO_SETTINGS_MODULE=my_geonode.settings paver sync
DJANGO_SETTINGS_MODULE=my_geonode.settings paver start
# Using the Custom Local Settings
# - Remember that `.settings` includes `.local_settings`
cp my_geonode/local_settings.py.sample my_geonode/local_settings.py
DJANGO_SETTINGS_MODULE=my_geonode.local_settings paver reset
DJANGO_SETTINGS_MODULE=my_geonode.local_settings paver setup
DJANGO_SETTINGS_MODULE=my_geonode.local_settings paver sync
DJANGO_SETTINGS_MODULE=my_geonode.local_settings paver start
```
3. Access GeoNode from browser
**NOTE**: default admin user is ``admin`` (with pw: ``admin``)
```bash
http://localhost:8000/
```
## Start your server using Docker
You need Docker 1.12 or higher, get the latest stable official release for your platform.
1. Prepare the Environment
```bash
git clone https://github.com/GeoNode/geonode-project.git -b <your_branch>
mkvirtualenv my_geonode
pip install Django==1.11.29
django-admin startproject --template=./geonode-project -e py,sh,md,rst,json,yml,ini,env,sample -n monitoring-cron -n Dockerfile my_geonode
cd my_geonode
```
2. Run `docker-compose` to start it up (get a cup of coffee or tea while you wait)
```bash
docker-compose build --no-cache
docker-compose up -d
```
```bash
set COMPOSE_CONVERT_WINDOWS_PATHS=1
```
before running `docker-compose up`
3. Access the site on http://localhost/
## Run the instance in development mode
### Use dedicated docker-compose files while developing
**NOTE**: In this example we are going to keep localhost as the target IP for GeoNode
```bash
docker-compose -f docker-compose.development.yml -f docker-compose.development.override.yml up
```
## Run the instance on a public site
### Preparation of the image (First time only)
**NOTE**: In this example we are going to publish to the public IP http://123.456.789.111
```bash
vim .env
--> replace localhost with 123.456.789.111 everywhere
```
### Startup the image
```bash
docker-compose up --build -d
```
### Stop the Docker Images
```bash
docker-compose stop
```
### Fully Wipe-out the Docker Images
**WARNING**: This will wipe out all the repositories created until now.
**NOTE**: The images must be stopped first
```bash
docker system prune -a
```
## Recommended: Track your changes
Step 1. Install Git (for Linux, Mac or Windows).
Step 2. Init git locally and do the first commit:
```bash
git init
git add *
git commit -m "Initial Commit"
```
Step 3. Set up a free account on github or bitbucket and make a copy of the repo there.
## Hints: Configuring `requirements.txt`
You may want to configure your requirements.txt, if you are using additional or custom versions of python packages. For example
```python
Django==1.11.29
git+git://github.com/<your organization>/geonode.git@<your branch>
```
## Hints: Using Ansible
You will need to use Ansible Role in order to run the playbook.
In order to install and setup Ansible, run the following commands
```bash
sudo apt-get install software-properties-common
sudo apt-add-repository ppa:ansible/ansible
sudo apt-get update
sudo apt-get install ansible
```
A sample Ansible Role can be found at https://github.com/GeoNode/ansible-geonode
To install the default one, run
```bash
sudo ansible-galaxy install GeoNode.geonode
```
you will find the Ansible files into the ``~/.ansible/roles`` folder. Those must be updated in order to match the GeoNode and GeoServer versions you will need to install.
To run the Ansible playbook use something like this
```bash
ANSIBLE_ROLES_PATH=~.ansible/roles ansible-playbook -e "gs_root_password=<new gs root password>" -e "gs_admin_password=<new gs admin password>" -e "dj_superuser_password=<new django admin password>" -i inventory --limit all playbook.yml
```
## Configuration
**NOTE**: *For `GeoNode` settings, make use of the `ENVIRONMENT` variables whenever is possible. Avoid overwriting them yourself, you might me missing some additional logic done on `geonode.settings`*
Since this application uses geonode, base source of settings is ``geonode.settings`` module. It provides defaults for many items, which are used by geonode. This application has own settings module, ``haitidata.settings``, which includes ``geonode.settings``. It customizes few elements:
* static/media files locations - they will be collected and stored along with this application files by default. This is useful during development.
* Adds ``haitidata`` to installed applications, updates templates, staticfiles dirs, sets urlconf to ``haitidata.urls``.
Whether you deploy development or production environment, you should create additional settings file. Convention is to make ``haitidata.local_settings`` module. It is recommended to use ``haitidata/local_settings.py``.. That file contains small subset of settings for edition. It should:
* not be versioned along with application (because changes you make for your private deployment may become public),
* have customized at least ``DATABASES``, ``SECRET_KEY`` and ``SITEURL``.
You can add more settings there, note however, some settings (notably ``DEBUG_STATIC``, ``EMAIL_ENABLE``, ``*_ROOT``, and few others) can be used by other settings, or as condition values, which change other settings. For example, ``EMAIL_ENABLE`` defined in ``geonode.settings`` enables whole email handling block, so if you disable it in your ``local_settings``, derived settings will be preserved. You should carefully check if additional settings you change don't trigger other settings.
To illustrate whole concept of chained settings:
|GeoNode configuration| |(optionally) Your deployment(s) | |Your application default configuration|
|---|---|---|---|---|
|`geonode.settings`|included by ->|`haitidata.local_settings`|included by ->|`haitidata.settings`|
-84
View File
@@ -1,84 +0,0 @@
Haitidata
========================
You should write some docs, it's good for the soul.
Installation
------------
Install geonode with::
$ sudo add-apt-repository ppa:geonode/stable
$ sudo apt-get update
$ sudo apt-get install geonode
Create a new template based on the geonode example project.::
$ django-admin startproject my_geonode --template=https://github.com/GeoNode/geonode-project/archive/2.6.zip -epy,rst
$ sudo pip install -e my_geonode
.. note:: You should NOT use the name geonode for your project as it will conflict with the default geonode package name.
Usage
-----
Rename the local_settings.py.sample to local_settings.py and edit it's content by setting the SITEURL and SITENAME.
Edit the file /etc/apache2/sites-available/geonode and change the following directive from:
WSGIScriptAlias / /var/www/geonode/wsgi/geonode.wsgi
to:
WSGIScriptAlias / /path/to/my_geonode/my_geonode/wsgi.py
To avoid having to grant apache permissions (i.e. www-data user and group) to your home dir where you likely setup the geonode-project; you may want to instead copy the wsgi.py file next to geonode.wsgi and replace the file name instead of the entire path.
$ cp /path/to/my_geonode/my_geonode/wsgi.py /var/www/geonode/wsgi/wsgi.py
Add the "Directory" directive for your folder like the following example:
<Directory "/home/vagrant/my_geonode/my_geonode/">
Order allow,deny
Options Indexes FollowSymLinks
Allow from all
Require all granted
IndexOptions FancyIndexing
</Directory>
Restart apache::
$ sudo service apache2 restart
Edit the templates in my_geonode/templates, the css and images to match your needs.
In the my_geonode folder run::
$ python manage.py collectstatic
Github Considerations
------------------------
While it is helpful to recommit your django project wrapper back to a distributed version control repository.
* It is also important to remember that production instances will store security information in the local_settings.py
* Admin/Devs should always remember to exclude this file in the .gitignore file in the same folder as the .git::
$ nano .gitignore
/{project}/local_settings.py
save, make sure the file is also removed from git cache::
$ git rm -f --cache //local_settings.py
$ git status
confirm the file is no longer staged for the next commit or that if it is as "removed"
-10
View File
@@ -1,10 +0,0 @@
from django.contrib import admin
from .models import Chart
class ChartAdmin(admin.ModelAdmin):
list_display = ['id', 'title']
admin.site.register(Chart, ChartAdmin)
-27
View File
@@ -1,27 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('layers', '24_to_26'),
]
operations = [
migrations.CreateModel(
name='Chart',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('title', models.CharField(max_length=128, blank=True)),
('category', models.CharField(max_length=200)),
('quantity', models.CharField(max_length=200)),
('type', models.SmallIntegerField(default=0, choices=[(0, b'Bar chart'), (1, b'Pie chart'), (2, b'Donut chart')])),
('aggr_type', models.SmallIntegerField(default=3, choices=[(0, b'Sum'), (1, b'Mean'), (2, b'Category count'), (3, b'Max'), (4, b'Min')])),
('abstract', models.TextField(blank=True)),
('layer', models.ForeignKey(to='layers.Layer')),
],
),
]
@@ -1,32 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.conf import settings
import charts_app.models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('charts_app', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='chart',
name='created_by',
field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=True),
),
migrations.AlterField(
model_name='chart',
name='layer',
field=models.ForeignKey(to='layers.Layer', validators=[charts_app.models.validate_wfs]),
),
migrations.AlterField(
model_name='chart',
name='type',
field=models.SmallIntegerField(default=0, choices=[(0, b'Bar chart'), (1, b'Pie chart'), (2, b'Donut chart'), (3, b'Line chart')]),
),
]
@@ -1,24 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('charts_app', '0002_auto_20170705_0742'),
]
operations = [
migrations.AlterField(
model_name='chart',
name='quantity',
field=models.CharField(max_length=200, blank=True),
),
migrations.AlterField(
model_name='chart',
name='title',
field=models.CharField(max_length=128),
),
]
-80
View File
@@ -1,80 +0,0 @@
from django.db import models
from django.core.urlresolvers import reverse
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from django.forms import ModelForm, ValidationError as VE
from geonode.layers.models import Layer
from wfs_harvest.utils import get_featno, get_fields
def validate_wfs(value):
lyr = Layer.objects.get(pk=value)
if lyr.service_type != 'WFS':
raise ValidationError(_('%(lyr_title)s is not a WFS layer'),
code='not_a_wfs',
params={'lyr_title': lyr.title})
feat_no = get_featno(value)
if feat_no > settings.MAX_CSV_RECORDS:
raise ValidationError(_('%(lyr_title)s has too many features; '
'chart functionality is not available '
'for very large datasets'),
code='too_many_records',
params={'lyr_title': lyr.title})
class Chart(models.Model):
CHART_TYPES = (
(0, 'Bar chart'),
(1, 'Pie chart'),
(2, 'Donut chart'),
(3, 'Line chart')
)
AGGREGATION_TYPES = (
(0, 'Sum'),
(1, 'Mean'),
(2, 'Category count'),
(3, 'Max'),
(4, 'Min'),
)
layer = models.ForeignKey(Layer, validators=[validate_wfs])
title = models.CharField(max_length=128, blank=False)
category = models.CharField(max_length=200)
quantity = models.CharField(max_length=200, blank=True)
type = models.SmallIntegerField(choices=CHART_TYPES, default=0)
aggr_type = models.SmallIntegerField(choices=AGGREGATION_TYPES, default=3)
abstract = models.TextField(blank=True)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null = True)
def get_absolute_url(self):
return reverse('chart_detail', kwargs={'pk': self.pk})
class ChartForm(ModelForm):
def clean(self):
cleaned_data = super(ChartForm, self).clean()
layer = cleaned_data.get('layer')
category = cleaned_data.get('category')
quantity = cleaned_data.get('quantity')
aggr_type = cleaned_data.get('aggr_type')
categories, quantities = get_fields(layer)
if category not in categories:
lyr = Layer.objects.get(pk=layer)
raise VE(_('%(lyr_title)s does not contain the field %(category)s'),
code='non_extant_category_field',
params={'lyr_title': lyr.title, 'category': category})
if quantity not in quantities and aggr_type != 2:
lyr = Layer.objects.get(pk=layer)
raise VE(_('%(lyr_title)s does not contain the field %(quantity)s'),
code='non_extant_quantity_field',
params={'lyr_title': lyr.title, 'quantity': quantity})
class Meta:
model = Chart
fields = '__all__'
-68
View File
@@ -1,68 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Donut Chart v1</title>
<h1>Simple Donut Chart v1</h1>
<h2>Zero values excluded</h2>
<p>D3js version 4, use canvas</p>
<canvas width="960" height="500"></canvas>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var canvas = document.querySelector("canvas"),
context = canvas.getContext("2d");
var width = canvas.width,
height = canvas.height,
radius = Math.min(width, height) / 2;
var colors = ["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00", "#800000", "#8E388E",
"#7171C6", "#7D9EC0", "#388E8E", "#71C671", "#8E8E38", "#C5C1AA", "#C67171"];
var arc = d3.arc()
.outerRadius(radius - 10)
.innerRadius(radius - 70)
.context(context);
var labelArc = d3.arc()
.outerRadius(radius - 40)
.innerRadius(radius - 40)
.context(context);
var pie = d3.pie()
.sort(null)
.value(function(d) { return d.area; });
context.translate(width / 2, height / 2);
d3.csv("{% url "get_csv" %}", function(d) {
d.area = +d.area;
if (d.area !== 0) {
return d;}
}, function(error, data) {
if (error) throw error;
var arcs = pie(data);
arcs.forEach(function(d, i) {
context.beginPath();
arc(d);
context.fillStyle = colors[i];
context.fill();
});
context.beginPath();
arcs.forEach(arc);
context.strokeStyle = "#fff";
context.stroke();
context.textAlign = "center";
context.textBaseline = "middle";
context.fillStyle = "#000";
arcs.forEach(function(d) {
var c = labelArc.centroid(d);
context.fillText(d.data.name, c[0], c[1]);
});
});
</script>
<body></body>
-169
View File
@@ -1,169 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Donut Chart v2</title>
<h1>Simple Donut Chart v2</h1>
<h2>Zero values excluded, label with ticks</h2>
<p>D3js version 3, use svg</p>
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
}
svg {
width: 100%;
height: 100%;
}
path.slice{
stroke-width:2px;
}
polyline{
opacity: .3;
stroke: black;
stroke-width: 2px;
fill: none;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var svg = d3.select("body")
.append("svg")
.append("g")
svg.append("g")
.attr("class", "slices");
svg.append("g")
.attr("class", "labels");
svg.append("g")
.attr("class", "lines");
var width = 960,
height = 500,
radius = Math.min(width, height) / 2;
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d.area;
});
var arc = d3.svg.arc()
.outerRadius(radius * 0.8)
.innerRadius(radius * 0.4);
var outerArc = d3.svg.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);
d3.csv("{% url "get_csv" %}", function(d) {
d.area = +d.area;
if (d.area !== 0) {
return d;}
}, function(error, data) {
if (error) throw error;
svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var key = function(d){ return d.data.name};
var color = d3.scale.ordinal()
.domain([key])
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var slice = svg.select(".slices").selectAll("path.slice")
.data(pie(data), key);
slice.enter()
.insert("path")
.style("fill", function(d) { return color(d.data.area); })
.attr("class", "slice");
slice
.transition().duration(1000)
.attrTween("d", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
return arc(interpolate(t));
};
})
/* ------- TEXT LABELS -------*/
var text = svg.select(".labels").selectAll("text")
.data(pie(data), key);
text.enter()
.append("text")
.attr("dy", ".35em")
.text(function(d) {
return d.data.name + ' - ' +d.data.area; ;
});
function midAngle(d){
return d.startAngle + (d.endAngle - d.startAngle)/2;
}
text.transition().duration(1000)
.attrTween("transform", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate("+ pos +")";
};
})
.styleTween("text-anchor", function(d){
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start":"end";
};
});
/* ------- SLICE TO TEXT POLYLINES -------*/
var polyline = svg.select(".lines").selectAll("polyline")
.data(pie(data), key);
polyline.enter()
.append("polyline");
polyline.transition().duration(1000)
.attrTween("points", function(d){
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
return [arc.centroid(d2), outerArc.centroid(d2), pos];
};
});
});
</script>
</body>
-65
View File
@@ -1,65 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Pie Chart v1</title>
<h1>Simple Pie Chart v1</h1>
<h2>All data</h2>
<p>D3js version 4, use svg</p>
<style>
.arc text {
font: 10px sans-serif;
text-anchor: middle;
}
.arc path {
stroke: #fff;
}
</style>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
radius = Math.min(width, height) / 2,
g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var color = d3.scaleOrdinal(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var pie = d3.pie()
.sort(null)
.value(function(d) { return d.area; });
var path = d3.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var label = d3.arc()
.outerRadius(radius - 40)
.innerRadius(radius - 40);
d3.csv("{% url "get_csv" %}", function(d) {
d.area = +d.area;
return d;
}, function(error, data) {
if (error) throw error;
var arc = g.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
arc.append("path")
.attr("d", path)
.attr("fill", function(d) { return color(d.data.name); });
arc.append("text")
.attr("transform", function(d) { return "translate(" + label.centroid(d) + ")"; })
.attr("dy", "0.35em")
.text(function(d) { return d.data.name; });
});
</script>
-67
View File
@@ -1,67 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Pie Chart v2</title>
<h1>Simple Pie Chart v2</h1>
<h2>Zero values excluded</h2>
<p>D3js version 4, use svg</p>
<style>
.arc text {
font: 10px sans-serif;
text-anchor: middle;
}
.arc path {
stroke: #fff;
}
</style>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
radius = Math.min(width, height) / 2,
g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var color = d3.scaleOrdinal(d3.schemeCategory20);
var pie = d3.pie()
.sort(null)
.value(function(d) { return d.{{ quantity }}; });
var path = d3.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var label = d3.arc()
.outerRadius(radius - 40)
.innerRadius(radius - 40);
d3.csv("/table?lyrname={{ lyrname }}&category={{ category }}&quantity={{ quantity }}", function(d) {
d.area = +d.area;
if (d.area !== 0) {
return d;}
}, function(error, data) {
if (error) throw error;
var arc = g.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
arc.append("path")
.attr("d", path)
.attr("fill", function(d) { return color(d.data.{{ category }}); });
arc.append("text")
.attr("transform", function(d) { return "translate(" + label.centroid(d) + ")"; })
.attr("dy", "0.35em")
.text(function(d) { return d.data.{{ category }}; });
});
</script>
-3
View File
@@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.
-10
View File
@@ -1,10 +0,0 @@
from django.conf.urls import url
from . import views
urlpatterns = [url(r'^(?P<pk>[0-9]+)/$', views.ChartDetail.as_view(), name='chart_detail'),
url(r'^add/(?P<layer_id>[0-9]+)/$', views.ChartCreate.as_view(), name='chart_add'),
url(r'^(?P<pk>[0-9]+)/update/$', views.ChartUpdate.as_view(), name='chart_update'),
url(r'^(?P<pk>[0-9]+)/delete/$', views.ChartDelete.as_view(), name='chart_delete'),
url(r'^$', views.ChartList.as_view(), name='chart_list')
]
-105
View File
@@ -1,105 +0,0 @@
from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.views.generic.list import ListView
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from geonode.layers.models import Layer
from .models import Chart, ChartForm
from wfs_harvest.utils import get_fields
class LoginRequiredMixin(object):
@classmethod
def as_view(cls, **initkwargs):
view = super(LoginRequiredMixin, cls).as_view(**initkwargs)
return login_required(view)
class ChartDetail(DetailView):
model = Chart
def get_object(self, queryset=None):
obj = super(ChartDetail, self).get_object(queryset=queryset)
lyr_obj = Layer.objects.get(pk=obj.layer)
if not self.request.user.has_perm('download_resourcebase', lyr_obj.get_self_resource()):
raise PermissionDenied
return obj
def get_context_data(self, **kwargs):
context = super(ChartDetail, self).get_context_data(**kwargs)
return context
class ChartCreate(LoginRequiredMixin, CreateView):
form_class = ChartForm
template_name = 'charts_app/chart_update_form.html'
def get_initial(self):
layer_id = self.kwargs['layer_id']
initial = self.initial.copy()
initial['layer'] = layer_id
return initial
def get_context_data(self, **kwargs):
layer_id = self.kwargs['layer_id']
layer = Layer.objects.get(pk=layer_id)
if not self.request.user.has_perm('download_resourcebase', layer.get_self_resource()):
raise PermissionDenied
fieldnames, num_fieldnames = get_fields(layer_id)
ctx = super(ChartCreate, self).get_context_data(**kwargs)
ctx['fieldnames'] = fieldnames
ctx['num_fieldnames'] = num_fieldnames
ctx['layer'] = layer
return ctx
def form_valid(self, form):
if not self.request.user.has_perm('download_resourcebase', form.instance.layer.get_self_resource()):
raise PermissionDenied
form.instance.created_by = self.request.user
return super(ChartCreate, self).form_valid(form)
class ChartUpdate(LoginRequiredMixin, UpdateView):
model = Chart
fields = '__all__'
template_name = 'charts_app/chart_update_form.html'
def get_object(self, queryset=None):
obj = super(ChartUpdate, self).get_object(queryset=queryset)
is_chart_owner = (self.request.user == obj.created_by)
lyr_obj = Layer.objects.get(pk=obj.layer)
is_lyr_owner = (self.request.user == lyr_obj.owner)
if not (self.request.user.is_superuser or is_chart_owner or is_lyr_owner):
raise PermissionDenied
return obj
def form_valid(self, form):
form.instance.created_by = self.request.user
return super(ChartUpdate, self).form_valid(form)
class ChartDelete(LoginRequiredMixin, DeleteView):
model = Chart
success_url = '/layers/'
def get_object(self, queryset=None):
obj = super(ChartDelete, self).get_object(queryset=queryset)
is_chart_owner = (self.request.user == obj.created_by)
lyr_obj = Layer.objects.get(pk=obj.layer)
is_lyr_owner = (self.request.user == lyr_obj.owner)
if not (self.request.user.is_superuser or is_chart_owner or is_lyr_owner):
raise PermissionDenied
return obj
class ChartList(ListView):
model = Chart
fields = '__all__'
template_name = 'charts_app/chart_list.html'
def get_context_data(self, **kwargs):
context = super(ChartList, self).get_context_data(**kwargs)
return context
View File
Whitespace-only changes.
File renamed without changes.
+6
View File
@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
# Register your models here.
+8
View File
@@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.apps import AppConfig
class ClipAndShipConfig(AppConfig):
name = 'clip_and_ship'
File renamed without changes.
+6
View File
@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
# Create your models here.
+6
View File
@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.test import TestCase
# Create your tests here.
File renamed without changes.
@@ -1,3 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import datetime
import os
import tempfile
@@ -6,20 +9,33 @@ import zipfile
import urllib2
import subprocess
from pyproj import Proj, transform
from django.conf import settings
from django.http import Http404, HttpResponse, JsonResponse
from django.shortcuts import render
from django.views.generic.detail import View
from geonode.layers.views import _resolve_layer, _PERMISSION_MSG_VIEW
from geonode.layers.models import Layer
WCS_URL = settings.GEOSERVER_BASE_URL + \
WCS_URL = settings.GEOSERVER_PUBLIC_LOCATION + \
'wcs?request=getcoverage&' \
'version=1.0.0&service=WCS&coverage={layer_name}&' \
'format=geotiff&crs=EPSG:4326&bbox={bbox}&width={width}&' \
'height={height}'
WCS_URL_2_0_1 = settings.GEOSERVER_BASE_URL + \
WCS_URL_2_0_1 = settings.GEOSERVER_PUBLIC_LOCATION + \
'wcs?request=getcoverage&' \
'version=2.0.1&service=WCS&coverageid={layer_name}&' \
'format=geotiff&crs=EPSG:4326&subset=E({x1},{x2})&subset=N({y1},{y2})'
WCS_URL_dev = settings.GEOSERVER_PUBLIC_LOCATION + \
'wcs?request=getcoverage&' \
'version=1.0.0&service=WCS&coverage={layer_name}&' \
'format=geotiff&crs=EPSG:4326&bbox={bbox}&width={width}&' \
'height={height}'
WCS_URL_2_0_1_dev = settings.GEOSERVER_PUBLIC_LOCATION + \
'wcs?request=getcoverage&' \
'version=2.0.1&service=WCS&coverageid={layer_name}&' \
'format=geotiff&crs=EPSG:4326&subset=E({x1},{x2})&subset=N({y1},{y2})'
@@ -62,12 +78,20 @@ def download_wcs(layername, bbox_string, width, height, raster_filepath):
:return:
"""
wcs_formatted_url = WCS_URL.format(
layer_name=layername,
bbox=bbox_string,
width=width,
height=height
)
if layername == 'geonode:ortho_images' or layername == 'geonode:lidar':
wcs_formatted_url = WCS_URL_dev.format(
layer_name=layername,
bbox=bbox_string,
width=width,
height=height
)
else:
wcs_formatted_url = WCS_URL.format(
layer_name=layername,
bbox=bbox_string,
width=width,
height=height
)
response = urllib2.urlopen(wcs_formatted_url)
fh = open(raster_filepath, "w")
@@ -83,13 +107,22 @@ def download_wcs_v2(layername, x1, x2, y1, y2, raster_filepath):
:return:
"""
wcs_formatted_url = WCS_URL_2_0_1.format(
layer_name=layername,
x1=x1,
x2=x2,
y1=y1,
y2=y2
)
if layername == 'geonode:ortho_images' or layername == 'geonode:lidar':
wcs_formatted_url = WCS_URL_2_0_1_dev.format(
layer_name=layername,
x1=x1,
x2=x2,
y1=y1,
y2=y2
)
else:
wcs_formatted_url = WCS_URL_2_0_1.format(
layer_name=layername,
x1=x1,
x2=x2,
y1=y1,
y2=y2
)
response = urllib2.urlopen(wcs_formatted_url)
fh = open(raster_filepath, "w")
@@ -106,11 +139,10 @@ def clip_layer(request, layername):
"""
# PREPARATION
try:
layer = _resolve_layer(
request,
layername,
'base.view_resourcebase',
_PERMISSION_MSG_VIEW)
layer = Layer.objects.get(
workspace=layername.split(':')[0],
name=layername.split(':')[1]
)
except Http404 as e:
response = JsonResponse({
'error': '%s. '
@@ -318,11 +350,10 @@ def download_clip(request, layername, clip_filename):
:return: The HTTPResponse with a file.
"""
# PREPARATION
layer = _resolve_layer(
request,
layername,
'base.view_resourcebase',
_PERMISSION_MSG_VIEW)
layer = Layer.objects.get(
workspace=layername.split(':')[0],
name=layername.split(':')[1]
)
query = request.GET or request.POST
params = {
@@ -401,7 +432,7 @@ def download_clip(request, layername, clip_filename):
class ClipView(View):
template_name = 'clip-and-ship/clip-page.html'
template_name = 'clip_and_ship/clip_page.html'
def get(self, request, geotiffname):
context = {
+9
View File
@@ -0,0 +1,9 @@
---
GEOSERVER_URL: "https://build.geo-solutions.it/geonode/geoserver/latest/geoserver-2.15.4.war"
DATA_DIR_URL: "https://build.geo-solutions.it/geonode/geoserver/latest/data-2.15.4.zip"
JETTY_RUNNER_URL: "https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-runner/9.4.7.v20170914/jetty-runner-9.4.7.v20170914.jar"
WINDOWS:
py2exe: "http://downloads.sourceforge.net/project/py2exe/py2exe/0.6.9/py2exe-0.6.9.win32-py2.7.exe"
nose: "https://s3.amazonaws.com/geonodedeps/nose-1.3.3.win32-py2.7.exe"
pyproj: "https://pyproj.googlecode.com/files/pyproj-1.9.3.win32-py2.7.exe"
lxml: "https://pypi.python.org/packages/2.7/l/lxml/lxml-3.6.0.win32-py2.7.exe"
+1
View File
@@ -0,0 +1 @@
docker-compose build --no-cache; docker-compose stop; docker-compose up -d; docker system prune -a
+10
View File
@@ -0,0 +1,10 @@
version: '2.2'
services:
django:
build: .
# Loading the app is defined here to allow for
# autoreload on changes it is mounted on top of the
# old copy that docker added when creating the image
volumes:
- '.:/usr/src/haitidata'
+113
View File
@@ -0,0 +1,113 @@
version: '2.2'
services:
db:
image: geonode/postgis:11
restart: unless-stopped
container_name: db4${COMPOSE_PROJECT_NAME}
stdin_open: true
# tty: true
labels:
org.geonode.component: db
org.geonode.instance.name: geonode
volumes:
- dbdata:/var/lib/postgresql/data
- dbbackups:/pg_backups
env_file:
- .env
geoserver:
image: geonode/geoserver:2.15.4
build: ./docker/geoserver/
restart: unless-stopped
container_name: geoserver4${COMPOSE_PROJECT_NAME}
stdin_open: true
# tty: true
labels:
org.geonode.component: geoserver
org.geonode.instance.name: geonode
depends_on:
- db
- data-dir-conf
volumes:
- geoserver-data-dir:/geoserver_data/data
env_file:
- .env
django:
restart: unless-stopped
build: .
container_name: django4${COMPOSE_PROJECT_NAME}
stdin_open: true
# tty: true
labels:
org.geonode.component: django
org.geonode.instance.name: geonode
depends_on:
- db
- data-dir-conf
# command: paver start_django -b 0.0.0.0:8000
# command: uwsgi --ini uwsgi.ini
volumes:
- statics:/mnt/volumes/statics
- geoserver-data-dir:/geoserver_data/data
env_file:
- .env
geonode:
image: geonode/nginx:geoserver
build: ./docker/nginx/
restart: unless-stopped
container_name: nginx4${COMPOSE_PROJECT_NAME}
stdin_open: true
# tty: true
labels:
org.geonode.component: nginx
org.geonode.instance.name: geonode
depends_on:
- django
- geoserver
ports:
- "80:80"
- "443:443"
volumes:
- nginx-confd:/etc/nginx
- nginx-certificates:/geonode-certificates
- statics:/mnt/volumes/statics
env_file:
- .env
# Gets and installs letsencrypt certificates
letsencrypt:
image: geonode/letsencrypt:2.10.4
build: ./docker/letsencrypt/
restart: on-failure
volumes:
- nginx-certificates:/geonode-certificates/
env_file:
- .env
data-dir-conf:
image: geonode/geoserver_data:2.15.4
restart: on-failure
container_name: gsconf4${COMPOSE_PROJECT_NAME}
labels:
org.geonode.component: conf
org.geonode.instance.name: geonode
command: /bin/true
volumes:
- geoserver-data-dir:/geoserver_data/data
volumes:
statics:
name: ${COMPOSE_PROJECT_NAME}-statics
nginx-confd:
name: ${COMPOSE_PROJECT_NAME}-nginxconfd
nginx-certificates:
name: ${COMPOSE_PROJECT_NAME}-nginxcerts
geoserver-data-dir:
name: ${COMPOSE_PROJECT_NAME}-gsdatadir
dbdata:
name: ${COMPOSE_PROJECT_NAME}-dbdata
dbbackups:
name: ${COMPOSE_PROJECT_NAME}-dbbackups
+1
View File
@@ -0,0 +1 @@
docker kill $(docker ps -q); docker rm $(docker ps -a -q); docker rmi $(docker images -q); docker volume ls -qf dangling=true | xargs -r docker volume rm; docker system prune -a
+97
View File
@@ -0,0 +1,97 @@
FROM tomcat:9-jre8
MAINTAINER GeoNode Development Team
#
# Set GeoServer version and data directory
#
ENV GEOSERVER_VERSION=2.15.4
ENV GEOSERVER_DATA_DIR="/geoserver_data/data"
#
# Download and install GeoServer
#
RUN cd /usr/local/tomcat/webapps \
&& wget --no-check-certificate --progress=bar:force:noscroll https://build.geo-solutions.it/geonode/geoserver/latest/geoserver-${GEOSERVER_VERSION}.war \
&& unzip -q geoserver-${GEOSERVER_VERSION}.war -d geoserver \
&& rm geoserver-${GEOSERVER_VERSION}.war \
&& mkdir -p $GEOSERVER_DATA_DIR
VOLUME $GEOSERVER_DATA_DIR
# added by simonelanucara https://github.com/simonelanucara
# Optionally add JAI, ImageIO and Marlin Render for improved Geoserver performance
WORKDIR /tmp
ARG JAI_IMAGEIO=true
RUN if [ "$JAI_IMAGEIO" = true ]; then \
wget https://github.com/bourgesl/marlin-renderer/releases/download/v0_9_3/marlin-0.9.3-Unsafe.jar && \
mv /tmp/marlin-0.9.3-Unsafe.jar /usr/local/tomcat/webapps/geoserver/WEB-INF/lib/ ; \
fi
###########docker host###############
# Set DOCKERHOST variable if DOCKER_HOST exists
ARG DOCKERHOST=${DOCKERHOST}
# for debugging
RUN echo -n #1===>DOCKERHOST=${DOCKERHOST}
#
ENV DOCKERHOST ${DOCKERHOST}
# for debugging
RUN echo -n #2===>DOCKERHOST=${DOCKERHOST}
###########docker host ip#############
# Set GEONODE_HOST_IP address if it exists
ARG GEONODE_HOST_IP=${GEONODE_HOST_IP}
# for debugging
RUN echo -n #1===>GEONODE_HOST_IP=${GEONODE_HOST_IP}
#
ENV GEONODE_HOST_IP ${GEONODE_HOST_IP}
# for debugging
RUN echo -n #2===>GEONODE_HOST_IP=${GEONODE_HOST_IP}
# If empty set DOCKER_HOST_IP to GEONODE_HOST_IP
ENV DOCKER_HOST_IP=${DOCKER_HOST_IP:-${GEONODE_HOST_IP}}
# for debugging
RUN echo -n #1===>DOCKER_HOST_IP=${DOCKER_HOST_IP}
# Trying to set the value of DOCKER_HOST_IP from DOCKER_HOST
RUN if ! [ -z ${DOCKER_HOST_IP} ]; \
then echo export DOCKER_HOST_IP=${DOCKERHOST} | \
sed 's/tcp:\/\/\([^:]*\).*/\1/' >> /root/.bashrc; \
else echo "DOCKER_HOST_IP is already set!"; fi
# for debugging
RUN echo -n #2===>DOCKER_HOST_IP=${DOCKER_HOST_IP}
# Set WEBSERVER public port
ARG PUBLIC_PORT=${PUBLIC_PORT}
# for debugging
RUN echo -n #1===>PUBLIC_PORT=${PUBLIC_PORT}
#
ENV PUBLIC_PORT=${PUBLIC_PORT}
# for debugging
RUN echo -n #2===>PUBLIC_PORT=${PUBLIC_PORT}
# set nginx base url for geoserver
RUN echo export NGINX_BASE_URL=http://${NGINX_HOST}:${NGINX_PORT}/ | \
sed 's/tcp:\/\/\([^:]*\).*/\1/' >> /root/.bashrc
# copy the script and perform the run of scripts from entrypoint.sh
RUN mkdir -p /usr/local/tomcat/tmp
WORKDIR /usr/local/tomcat/tmp
COPY set_geoserver_auth.sh /usr/local/tomcat/tmp
COPY setup_auth.sh /usr/local/tomcat/tmp
COPY requirements.txt /usr/local/tomcat/tmp
COPY get_dockerhost_ip.py /usr/local/tomcat/tmp
COPY get_nginxhost_ip.py /usr/local/tomcat/tmp
COPY entrypoint.sh /usr/local/tomcat/tmp
RUN apt-get update \
&& apt-get -y upgrade \
&& apt-get install -y python python-pip python-dev \
&& chmod +x /usr/local/tomcat/tmp/set_geoserver_auth.sh \
&& chmod +x /usr/local/tomcat/tmp/setup_auth.sh \
&& chmod +x /usr/local/tomcat/tmp/entrypoint.sh \
&& pip install pip==9.0.3 \
&& pip install -r requirements.txt \
&& chmod +x /usr/local/tomcat/tmp/get_dockerhost_ip.py \
&& chmod +x /usr/local/tomcat/tmp/get_nginxhost_ip.py
ENV JAVA_OPTS="-Djava.awt.headless=true -XX:MaxPermSize=512m -XX:PermSize=256m -Xms512m -Xmx2048m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:ParallelGCThreads=4 -Dfile.encoding=UTF8 -Duser.timezone=GMT -Djavax.servlet.request.encoding=UTF-8 -Djavax.servlet.response.encoding=UTF-8 -Duser.timezone=GMT -Dorg.geotools.shapefile.datetime=true"
CMD ["/usr/local/tomcat/tmp/entrypoint.sh"]
+128
View File
@@ -0,0 +1,128 @@
# geoserver-docker
[GeoServer](http://geoserver.org) is an open source server for sharing geospatial data.
This is a docker image that eases setting up a GeoServer running specifically for [GeoNode](https://github.com/GeoNode/geoserver-geonode-ext) with an additional separated data directory.
The image is based on the official Tomcat 9 image
## Installation
This image is available as a [trusted build on the docker hub](https://registry.hub.docker.com/r/geonode/geoserver/), and is the recommended method of installation.
Simple pull the image from the docker hub.
```bash
$ docker pull geonode/geoserver
```
Alternatively you can build the image locally
```bash
$ git clone https://github.com/geonode/geoserver-docker.git
$ cd geoserver-docker
$ docker build -t "geonode/geoserver" .
```
## Quick start
You can quick start the image using the command line
```bash
$ docker run --name "geoserver" -v /var/run/docker.sock:/var/run/docker.sock -d -p 8080:8080 geonode/geoserver
```
Point your browser to `http://localhost:8080/geoserver` and login using GeoServer's default username and password:
* Username: admin
* Password: geoserver
## How to use different versions
There are mainly two different versions of this image which are useful for running **GeoNode** with different authentication system types. These versions are released as specific tags for two authentication mechanisms:
**Cookie based authn**:
- [geonode/geoserver:2.9.x](https://hub.docker.com/r/geonode/geoserver/builds/bx7ydhghnlrfnsppduyva73/)
**Oauth2 based authn**:
- [geonode/geoserver:2.9.x-oauth2](https://hub.docker.com/r/geonode/geoserver/builds/bwca5rtexeoegzgroavftdr/)
- [geonode/geoserver:2.10.x](https://hub.docker.com/r/geonode/geoserver/builds/bjohcnc29vm69acqjrvndxf/)
- [geonode/geoserver:2.12.x](https://hub.docker.com/r/geonode/geoserver/builds/bh7pyw5atmkcljurwsnzbs7/)
- [geonode/geoserver:2.13.x](https://hub.docker.com/r/geonode/geoserver/builds/btmjctbuvrjfnnrxrs4wyrs/)
- [geonode/geoserver:2.14.x](https://hub.docker.com/r/geonode/geoserver/builds/bj53pi8he8uksz6ggvrs3wc/)
You can declare what version to use along with the data directory tag which corresponds to the same version.
## Configuration
### Data volume
This GeoServer container keeps its configuration data at `/geoserver_data/data` which is exposed as volume in the dockerfile.
The volume allows for stopping and starting new containers from the same image without losing all the data and custom configuration.
You may want to map this volume to a directory on the host. It will also ease the upgrade process in the future. Volumes can be mounted by passing the `-v` flag to the docker run command:
```bash
-v /your/host/data/path:/geoserver_data/data
```
### Data volume container
In case you are running Compose for automatically having GeoServer up and running then a data volume container will be mounted with a default preloaded *GEOSERVER_DATA_DIR* at the configuration data directory of the container.
Make sure that the image from the repository [data-docker](https://github.com/GeoNode/data-docker) is available from the [GeoNode Docker Hub](https://hub.docker.com/u/geonode/) or has been built locally:
```bash
docker build -t geonode/geoserver_data .
```
#### Persistance behavior
If you run:
```bash
docker-compose stop
```
Data are retained in the *GEOSERVER_DATA_DIR* and can then be mounted in a new GeoServer instance by running again:
```bash
docker-compose up
```
If you run:
```bash
docker-compose down
```
Data are completely gone but you can ever start from the base GeoServer Data Directory built for Geonode.
#### Data directory versions
There has to be a correspondence one-to-one between the data directory version and the tag of the GeoServer image used in the Docker compose file. So at the end you can consume these images below:
* **2.9.x**: [geonode/geoserver_data:2.9.x](https://hub.docker.com/r/geonode/geoserver_data/builds/bsus6alnddg4bc7icwymevp/)
* **2.9.x-oauth2**: [geonode/geoserver_data:2.9.x-oauth2](https://hub.docker.com/r/geonode/geoserver_data/builds/bwkxcupsunvuitzusi9gsnt/)
* **2.10.x**: [geonode/geoserver_data:2.10.x](https://hub.docker.com/r/geonode/geoserver_data/builds/b5jqhpzapkqxzyevjizccug/)
* **2.12.x**: [geonode/geoserver_data:2.12.x](https://hub.docker.com/r/geonode/geoserver_data/builds/byaaalw3lnasunpveyg3x4i/)
* **2.13.x**: [geonode/geoserver_data:2.13.x](https://hub.docker.com/r/geonode/geoserver_data/builds/bunuqzq7a7dk65iumjhkbtc/)
* **2.14.x**: [geonode/geoserver_data:2.14.x](https://hub.docker.com/r/geonode/geoserver_data/builds/blpdjzkrv7pm3stunzpn4pp/)
### Database
GeoServer recommends the usage of a spatial database
#### PostGIS container (PostgreSQL + GIS Extension)
If you want to use a [PostGIS](http://postgis.org/) container, you can link it to this image. You're free to use any PostGIS container.
An example with [kartooza/postgis](https://registry.hub.docker.com/u/kartoza/postgis/) image:
```bash
$ docker run -d --name="postgis" kartoza/postgis
```
For further information see [kartooza/postgis](https://registry.hub.docker.com/u/kartoza/postgis/).
Now start the GeoServer instance by adding the `--link` option to the docker run command:
```bash
--link postgis:postgis
```
+48
View File
@@ -0,0 +1,48 @@
version: '2.2'
services:
geoserver:
image: geonode/geoserver:2.15.4
build:
context: .
args:
- DOCKERHOST
- GEONODE_HOST_IP
- PUBLIC_PORT=80
links:
- postgis
ports:
- "8080:8080"
volumes:
#- /srv/docker/geoserver/geoserver:/geoserver_data/data
volumes_from:
# reference to the service which has the volume
# with the preloaded geoserver_data_dir
- data_dir_conf # service for geoserver data volume
environment:
- DOCKERHOST
- GEONODE_HOST_IP
- PUBLIC_PORT=80
- DOCKER_HOST_IP
- DJANGO_URL=http://localhost/
data_dir_conf:
image: geonode/geoserver_data:2.15.4
container_name: geoserver_data_dir # named data container
command: /bin/true
volumes:
- /geoserver_data/data
postgis:
image: geonode/postgis
ports:
- "25432:5432"
volumes:
- /srv/docker/geoserver/postgis:/var/lib/postgresql
#volumes_from:
#- pgstore
volumes:
# reference to the named data container that holds the preloaded geoserver data directory
geoserver_data_dir:
+103
View File
@@ -0,0 +1,103 @@
#!/bin/bash
set -e
source /root/.bashrc
# control the value of DOCKER_HOST_IP variable
if [ -z ${DOCKER_HOST_IP} ]
then
echo "DOCKER_HOST_IP is empty so I'll run the python utility \n" >> /usr/local/tomcat/tmp/set_geoserver_auth.log
echo export DOCKER_HOST_IP=`python /usr/local/tomcat/tmp/get_dockerhost_ip.py` >> /root/.override_env
echo "The calculated value is now DOCKER_HOST_IP='$DOCKER_HOST_IP' \n" >> /usr/local/tomcat/tmp/set_geoserver_auth.log
else
echo "DOCKER_HOST_IP is filled so I'll leave the found value '$DOCKER_HOST_IP' \n" >> /usr/local/tomcat/tmp/set_geoserver_auth.log
fi
# control the values of LB settings if present
if [ ${GEONODE_LB_HOST_IP} ]
then
echo "GEONODE_LB_HOST_IP is filled so I replace the value of '$DOCKER_HOST_IP' with '$GEONODE_LB_HOST_IP' \n" >> /usr/local/tomcat/tmp/set_geoserver_auth.log
echo export DOCKER_HOST_IP=${GEONODE_LB_HOST_IP} >> /root/.override_env
fi
if [ ${GEONODE_LB_PORT} ]
then
echo "GEONODE_LB_PORT is filled so I replace the value of '$PUBLIC_PORT' with '$GEONODE_LB_PORT' \n" >> /usr/local/tomcat/tmp/set_geoserver_auth.log
echo export PUBLIC_PORT=${GEONODE_LB_PORT} >> /root/.override_env
fi
if [ ! -z "${GEOSERVER_JAVA_OPTS}" ]
then
echo "GEOSERVER_JAVA_OPTS is filled so I replace the value of '$JAVA_OPTS' with '$GEOSERVER_JAVA_OPTS' \n" >> /usr/local/tomcat/tmp/set_geoserver_auth.log
JAVA_OPTS=${GEOSERVER_JAVA_OPTS}
fi
# control the value of NGINX_BASE_URL variable
if [ -z `echo ${NGINX_BASE_URL} | sed 's/http:\/\/\([^:]*\).*/\1/'` ]
then
echo "NGINX_BASE_URL is empty so I'll use the static nginx hostname \n" >> /usr/local/tomcat/tmp/set_geoserver_auth.log
# echo export NGINX_BASE_URL=`python /usr/local/tomcat/tmp/get_nginxhost_ip.py` >> /root/.override_env
# TODO rework get_nginxhost_ip to get URL with static hostname from nginx service name
# + exposed port of that container i.e. http://geonode:80
echo export NGINX_BASE_URL=http://geonode:80 >> /root/.override_env
echo "The calculated value is now NGINX_BASE_URL='$NGINX_BASE_URL' \n" >> /usr/local/tomcat/tmp/set_geoserver_auth.log
else
echo "NGINX_BASE_URL is filled so I'll leave the found value '$NGINX_BASE_URL' \n" >> /usr/local/tomcat/tmp/set_geoserver_auth.log
fi
# set basic tagname
TAGNAME=( "baseUrl" )
if ! [ -f ${GEOSERVER_DATA_DIR}/security/auth/geonodeAuthProvider/config.xml ]
then
echo "Configuration file '$GEOSERVER_DATA_DIR'/security/auth/geonodeAuthProvider/config.xml is not available so it is gone to skip \n" >> /usr/local/tomcat/tmp/set_geoserver_auth.log
else
# backup geonodeAuthProvider config.xml
cp ${GEOSERVER_DATA_DIR}/security/auth/geonodeAuthProvider/config.xml ${GEOSERVER_DATA_DIR}/security/auth/geonodeAuthProvider/config.xml.orig
# run the setting script for geonodeAuthProvider
/usr/local/tomcat/tmp/set_geoserver_auth.sh ${GEOSERVER_DATA_DIR}/security/auth/geonodeAuthProvider/config.xml ${GEOSERVER_DATA_DIR}/security/auth/geonodeAuthProvider/ ${TAGNAME} >> /usr/local/tomcat/tmp/set_geoserver_auth.log
fi
# backup geonode REST role service config.xml
cp "${GEOSERVER_DATA_DIR}/security/role/geonode REST role service/config.xml" "${GEOSERVER_DATA_DIR}/security/role/geonode REST role service/config.xml.orig"
# run the setting script for geonode REST role service
/usr/local/tomcat/tmp/set_geoserver_auth.sh "${GEOSERVER_DATA_DIR}/security/role/geonode REST role service/config.xml" "${GEOSERVER_DATA_DIR}/security/role/geonode REST role service/" ${TAGNAME} >> /usr/local/tomcat/tmp/set_geoserver_auth.log
# set oauth2 filter tagname
TAGNAME=( "accessTokenUri" "userAuthorizationUri" "redirectUri" "checkTokenEndpointUrl" "logoutUri" )
# backup geonode-oauth2 config.xml
cp ${GEOSERVER_DATA_DIR}/security/filter/geonode-oauth2/config.xml ${GEOSERVER_DATA_DIR}/security/filter/geonode-oauth2/config.xml.orig
# run the setting script for geonode-oauth2
/usr/local/tomcat/tmp/set_geoserver_auth.sh ${GEOSERVER_DATA_DIR}/security/filter/geonode-oauth2/config.xml ${GEOSERVER_DATA_DIR}/security/filter/geonode-oauth2/ "${TAGNAME[@]}" >> /usr/local/tomcat/tmp/set_geoserver_auth.log
# set global tagname
TAGNAME=( "proxyBaseUrl" )
# backup global.xml
cp ${GEOSERVER_DATA_DIR}/global.xml ${GEOSERVER_DATA_DIR}/global.xml.orig
# run the setting script for global configuration
/usr/local/tomcat/tmp/set_geoserver_auth.sh ${GEOSERVER_DATA_DIR}/global.xml ${GEOSERVER_DATA_DIR}/ ${TAGNAME} >> /usr/local/tomcat/tmp/set_geoserver_auth.log
# set correct amqp broker url
sed -i -e 's/localhost/rabbitmq/g' ${GEOSERVER_DATA_DIR}/notifier/notifier.xml
# exclude wrong dependencies
sed -i -e 's/xom-\*\.jar/xom-\*\.jar,bcprov\*\.jar/g' /usr/local/tomcat/conf/catalina.properties
# start tomcat
exec env JAVA_OPTS="${JAVA_OPTS}" catalina.sh run
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/env python
import logging
import docker
BOOTSTRAP_IMAGE_CHEIP = 'codenvy/che-ip:nightly'
# AF: why call before definition? print _docker_host_ip()
def _docker_host_ip():
client = docker.from_env()
ip_list = client.containers.run(BOOTSTRAP_IMAGE_CHEIP,
network_mode='host'
).split("\n")
if len(ip_list) > 1:
logging.info("Docker daemon is running on more than one \
address {0}".format(ip_list))
logging.info("Only the first address:{0} will be returned!".format(
ip_list[0]
))
else:
logging.info("Docker daemon is running at the following \
address {0}".format(ip_list[0]))
return ip_list[0]
+45
View File
@@ -0,0 +1,45 @@
#!/usr/bin/env python
import logging
import os
import docker
client = docker.from_env()
# print client.info()
# TODO avoid this script can fail and fall in the loop where the geoserver
# service is not available and consequently the nginx too which has geoserver
# as a reference link
for network in client.networks.list():
if 'geonode' in network.name:
geonode_network = network.name
else:
geonode_network = 'geonode_default'
try:
containers = {
c.attrs['Config']['Image']: c.attrs['NetworkSettings']['\
Networks'][geonode_network]['\
IPAddress'] for c in client.containers.list() if c.status in 'running'
}
for item in containers.items():
if "geonode/nginx" in item[0]:
ipaddr = item[1]
try:
os.environ["NGINX_BASE_URL"] = "http://" + ipaddr + ":" + "80"
nginx_base_url = "http://{}:80".format(ipaddr)
except NameError as er:
logging.info("NGINX container is not running maybe exited! Running\
containers are:{0}".format(containers))
except KeyError as ke:
logging.info("There has been a problem with the docker\
network which has raised the following exception: {0}".format(ke))
else:
# nginx_base_url = None
pass
finally:
try:
print nginx_base_url
except NameError as ne:
print "http://geonode:80"
+1
View File
@@ -0,0 +1 @@
docker==3.1.1
+91
View File
@@ -0,0 +1,91 @@
#!/bin/bash
auth_conf_source="$1"
auth_conf_target="$2"
# Creating a temporary file for sed to write the changes to
temp_file="xml.tmp"
touch $temp_file
source /root/.bashrc
source /root/.override_env
test -z "$auth_conf_source" && echo "You must specify a source file" && exit 1
test -z "$auth_conf_target" && echo "You must specify a target conf directory" && exit 1
test ! -f "$auth_conf_source" && echo "Source $auth_conf_source does not exist or is not a file" && exit 1
test ! -d "$auth_conf_target" && echo "Target directory $auth_conf_target does not exist or is not a directory" && exit 1
# for debugging
echo -e "NGINX_BASE_URL=${NGINX_BASE_URL}\n"
if [ "$PUBLIC_PORT" == "443" ]; then
SUBSTITUTION_URL="https://${DOCKER_HOST_IP}"
if [ "$PUBLIC_PORT" != "443" ]; then
SUBSTITUTION_URL="https://${DOCKER_HOST_IP}:${PUBLIC_PORT}"
fi
else
SUBSTITUTION_URL="http://${DOCKER_HOST_IP}"
if [ "$PUBLIC_PORT" != "80" ]; then
SUBSTITUTION_URL="http://${DOCKER_HOST_IP}:${PUBLIC_PORT}"
fi
fi
echo -e "SUBSTITUTION_URL=$SUBSTITUTION_URL\n"
echo -e "auth_conf_source=$auth_conf_source\n"
echo -e "auth_conf_target=$auth_conf_target\n"
# Elegance is the key -> adding an empty last line for Mr. “sed” to pick up
echo " " >> "$auth_conf_source"
cat "$auth_conf_source"
tagname=( ${@:3:5} )
# for debugging
for i in "${tagname[@]}"
do
echo "tagname=<$i>"
done
echo "DEBUG: Starting... [Ok]\n"
for i in "${tagname[@]}"
do
echo "DEBUG: Working on '$auth_conf_source' for tagname <$i>"
# Extracting the value from the <$tagname> element
# echo -ne "<$i>$tagvalue</$i>" | xmlstarlet sel -t -m "//a" -v . -n
tagvalue=`grep "<$i>.*<.$i>" "$auth_conf_source" | sed -e "s/^.*<$i/<$i/" | cut -f2 -d">"| cut -f1 -d"<"`
echo "DEBUG: Found the current value for the element <$i> - '$tagvalue'"
# Setting new substituted value
case $i in
proxyBaseUrl )
if [ ${GEONODE_LB_HOST_IP} ]
then
echo "DEBUG: Editing '$auth_conf_source' for tagname <$i> and replacing its value with '$SUBSTITUTION_URL'"
newvalue=`echo -ne "$tagvalue" | sed -re "s@http://localhost(:8.*0)@$SUBSTITUTION_URL@"`
else
echo "DEBUG: Editing '$auth_conf_source' for tagname <$i> and replacing its value with '$NGINX_BASE_URL'"
newvalue=`echo -ne "$tagvalue" | sed -re "s@http://localhost(:8.*0)@$NGINX_BASE_URL@"`
fi;;
accessTokenUri | checkTokenEndpointUrl | baseUrl )
echo "DEBUG: Editing '$auth_conf_source' for tagname <$i> and replacing its value with '$NGINX_BASE_URL'"
newvalue=`echo -ne "$tagvalue" | sed -re "s@http://localhost(:8.*0)@$NGINX_BASE_URL@"`;;
userAuthorizationUri | redirectUri | logoutUri )
echo "DEBUG: Editing '$auth_conf_source' for tagname <$i> and replacing its value with '$SUBSTITUTION_URL'"
newvalue=`echo -ne "$tagvalue" | sed -re "s@http://localhost(:8.*0)@$SUBSTITUTION_URL@"`;;
*) echo -n "an unknown variable has been found";;
esac
echo "DEBUG: Found the new value for the element <$i> - '$newvalue'"
# Replacing element’s value with $SUBSTITUTION_URL
# echo -ne "<$i>$tagvalue</$i>" | xmlstarlet sel -t -m "//a" -v . -n
sed -e "s@<$i>$tagvalue<\/$i>@<$i>$newvalue<\/$i>@g" "$auth_conf_source" > "$temp_file"
cp "$temp_file" "$auth_conf_source"
done
# Writing our changes back to the original file ($auth_conf_source)
# no longer needed
# mv $temp_file $auth_conf_source
echo "DEBUG: Finished... [Ok] --- Final xml file is \n"
cat "$auth_conf_source"
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
sed -i.bak 's@<baseUrl>\([^<][^<]*\)</baseUrl>@<baseUrl>'"$DJANGO_URL"'</baseUrl>@'\
/geoserver_data/data/security/auth/geonodeAuthProvider/config.xml
+19
View File
@@ -0,0 +1,19 @@
FROM alpine:3.8
# 1-2. Install system dependencies
RUN apk add --no-cache certbot py-pip && pip install pyopenssl==16.0.0 # Need to downgrade PyOpenSSL to 16.0.0 to avoid conflicts and solve the cryptography error : https://github.com/plesk/letsencrypt-plesk/issues/117
# Installing scripts
ADD docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh
# Installing cronjobs
ADD crontab /crontab
RUN /usr/bin/crontab /crontab && \
rm /crontab
# Setup the entrypoint
ENTRYPOINT ["./docker-entrypoint.sh"]
# We run cron in foreground to update the certificates
CMD /usr/sbin/crond -f
+16
View File
@@ -0,0 +1,16 @@
ervice for SPCGeonode
This service generates SSL certificates to be used by Nginx.
## Let's Encrypt
Upon startup, it generates one SSL certificate from Let's Encrypt using Certbot. It then starts cron (in foreground) to renew the certificates using Certbot renew.
If for some reason getting the certificate fails, a placeholder certificate is generated. This certificate is invalid, but still allows to encrypt the data and to start the webserver.
To avoid hitting Let's Encrypt very low rate limits when developping or doing tests, LETSENCRYPT_MODE env var can be set to "disabled" (which will completely bypass Let'sEncrypt, simulating a failure) or to "staging" (using Let'sEncrypt test certificates with higher rates).
## Autoissued
An auto-issued certificate is also generate to be used on the LAN if needed. It is also renewed every now and then using the same cron process than above.
+9
View File
@@ -0,0 +1,9 @@
# .............. minute (0 - 59)
# . .............. hour (0 - 23)
# . . .............. day of month (1 - 31)
# . . . .............. month (1 - 12)
# . . . . .............. day of week (0 - 6) (Sunday to Saturday; 7 is also Sunday on some systems)
# . . . . .
0 0,12 * * * date && echo "daily " && /docker-entrypoint.sh
+49
View File
@@ -0,0 +1,49 @@
#!/bin/sh
# Exit script in case of error
set -e
echo $"\n\n\n"
echo "-----------------------------------------------------"
echo "STARTING LETSENCRYPT ENTRYPOINT ---------------------"
date
# We make the config dir
mkdir -p "/geonode-certificates/$LETSENCRYPT_MODE"
# Do not exit script in case of error
set +e
# We run the command
if [ "$LETSENCRYPT_MODE" == "staging" ]; then
printf "\nTrying to get STAGING certificate\n"
certbot --config-dir "/geonode-certificates/$LETSENCRYPT_MODE" certonly --webroot -w "/geonode-certificates" -d "$HTTPS_HOST" -m "$ADMIN_EMAIL" --agree-tos --non-interactive --staging --server https://acme-v02.api.letsencrypt.org/directory
elif [ "$LETSENCRYPT_MODE" == "production" ]; then
printf "\nTrying to get PRODUCTION certificate\n"
certbot --config-dir "/geonode-certificates/$LETSENCRYPT_MODE" certonly --webroot -w "/geonode-certificates" -d "$HTTPS_HOST" -m "$ADMIN_EMAIL" --agree-tos --non-interactive --server https://acme-v02.api.letsencrypt.org/directory
else
printf "\nNot trying to get certificate (simulating failure, because LETSENCRYPT_MODE variable was neither staging nor production\n"
/bin/false
fi
# If the certbot comand failed, we will create a placeholder certificate
if [ ! $? -eq 0 ]; then
# Exit script in case of error
set -e
printf "\nFailed to get the certificates !\n"
printf "\nWaiting 30s to avoid hitting Letsencrypt rate limits before it's even possible to react\n"
sleep 30
exit 1
fi
printf "\nCertificate have been created/renewed successfully\n"
echo "-----------------------------------------------------"
echo "FINISHED LETSENCRYPT ENTRYPOINT ---------------------"
echo "-----------------------------------------------------"
# Run the CMD
exec "$@"
+15
View File
@@ -0,0 +1,15 @@
FROM nginx:1.17.2-alpine
RUN apk add --no-cache openssl inotify-tools
WORKDIR /etc/nginx/
ADD nginx.conf.envsubst nginx.https.available.conf.envsubst ./
ADD geonode.conf ./sites-enabled/
ADD docker-autoreload.sh docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
RUN chmod +x /docker-autoreload.sh
RUN chmod +x /docker-entrypoint.sh
CMD ["nginx", "-g", "daemon off;"]
+37
View File
@@ -0,0 +1,37 @@
#!/bin/sh
# This will watch the /geonode-certificates folder and run nginx -s reload whenever there are some changes.
# We use this to reload nginx config when certificates changed.
# inspired/copied from https://github.com/kubernetes/kubernetes/blob/master/examples/https-nginx/auto-reload-nginx.sh
while true
do
inotifywait -e create -e modify -e delete -e move -r --exclude "\\.certbot\\.lock|\\.well-known" "/geonode-certificates/$LETSENCRYPT_MODE"
echo "Changes noticed in /geonode-certificates"
echo "Waiting 5s for additionnal changes"
sleep 5
echo "Creating symbolic link for WAN host"
# for some reason, the ln -f flag doesn't work below...
rm -f /certificate_symlink
if [ -f "/geonode-certificates/$LETSENCRYPT_MODE/live/$HTTPS_HOST/fullchain.pem" ] && [ -f "/geonode-certificates/$LETSENCRYPT_MODE/live/$HTTPS_HOST/privkey.pem" ]; then
echo "Certbot certificate exists, we symlink to the live cert"
ln -sf "/geonode-certificates/$LETSENCRYPT_MODE/live/$HTTPS_HOST" /certificate_symlink
else
echo "Certbot certificate does not exist, we symlink to autoissued"
ln -sf "/geonode-certificates/autoissued" /certificate_symlink
fi
# Test nginx configuration
nginx -t
# If it passes, we reload
if [ $? -eq 0 ]
then
echo "Configuration valid, we reload..."
nginx -s reload
else
echo "Configuration not valid, we do not reload."
fi
done
+54
View File
@@ -0,0 +1,54 @@
#!/bin/sh
# Exit script in case of error
set -e
echo $"\n\n\n"
echo "-----------------------------------------------------"
echo "STARTING NGINX ENTRYPOINT ---------------------------"
date
# We make the config dir
mkdir -p "/geonode-certificates/$LETSENCRYPT_MODE"
echo "Creating autoissued certificates for HTTP host"
if [ ! -f "/geonode-certificates/autoissued/privkey.pem" ] || [[ $(find /geonode-certificates/autoissued/privkey.pem -mtime +365 -print) ]]; then
echo "Autoissued certificate does not exist or is too old, we generate one"
mkdir -p "/geonode-certificates/autoissued/"
openssl req -x509 -nodes -days 1825 -newkey rsa:2048 -keyout "/geonode-certificates/autoissued/privkey.pem" -out "/geonode-certificates/autoissued/fullchain.pem" -subj "/CN=${HTTP_HOST:-null}"
else
echo "Autoissued certificate already exists"
fi
echo "Creating symbolic link for HTTPS certificate"
# for some reason, the ln -f flag doesn't work below...
# TODO : not DRY (reuse same scripts as docker-autoreload.sh)
rm -f /certificate_symlink
if [ -f "/geonode-certificates/$LETSENCRYPT_MODE/live/$HTTPS_HOST/fullchain.pem" ] && [ -f "/geonode-certificates/$LETSENCRYPT_MODE/live/$HTTPS_HOST/privkey.pem" ]; then
echo "Certbot certificate exists, we symlink to the live cert"
ln -sf "/geonode-certificates/$LETSENCRYPT_MODE/live/$HTTPS_HOST" /certificate_symlink
else
echo "Certbot certificate does not exist, we symlink to autoissued"
ln -sf "/geonode-certificates/autoissued" /certificate_symlink
fi
echo "Replacing environement variables"
envsubst '\$HTTP_HOST \$HTTPS_HOST \$RESOLVER' < /etc/nginx/nginx.conf.envsubst > /etc/nginx/nginx.conf
envsubst '\$HTTP_HOST \$HTTPS_HOST \$RESOLVER' < /etc/nginx/nginx.https.available.conf.envsubst > /etc/nginx/nginx.https.available.conf
echo "Enabling or not https configuration"
if [ -z "${HTTPS_HOST}" ]; then
echo "" > /etc/nginx/nginx.https.enabled.conf
else
ln -sf /etc/nginx/nginx.https.available.conf /etc/nginx/nginx.https.enabled.conf
fi
echo "Loading nginx autoreloader"
sh /docker-autoreload.sh &
echo "-----------------------------------------------------"
echo "FINISHED NGINX ENTRYPOINT ---------------------------"
echo "-----------------------------------------------------"
# Run the CMD
exec "$@"
+117
View File
@@ -0,0 +1,117 @@
include /etc/nginx/mime.types;
# This is the main geonode conf
charset utf-8;
# max upload size
client_max_body_size 100G;
client_body_buffer_size 256K;
large_client_header_buffers 4 64k;
proxy_read_timeout 600s;
fastcgi_hide_header Set-Cookie;
etag on;
# compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_http_version 1.1;
gzip_disable "MSIE [1-6]\.";
gzip_buffers 16 8k;
gzip_min_length 1100;
gzip_comp_level 6;
gzip_types
text/css
text/javascript
text/xml
text/plain
application/xml
application/xml+rss
application/javascript
application/x-javascript
application/json;
# GeoServer
location /geoserver {
# Using a variable is a trick to let Nginx start even if upstream host is not up yet
# (see https://sandro-keil.de/blog/2017/07/24/let-nginx-start-if-upstream-host-is-unavailable-or-down/)
set $upstream geoserver:8080;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://$upstream;
}
# GeoNode
location /static/ {
alias /mnt/volumes/statics/static/;
location ~* \.(?:html|js|jpg|jpeg|gif|png|css|tgz|gz|rar|bz2|doc|pdf|ppt|tar|wav|bmp|ttf|rtf|swf|ico|flv|txt|woff|woff2|svg|xml)$ {
gzip_static always;
expires 30d;
access_log off;
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
}
}
location /uploaded/ {
alias /mnt/volumes/statics/uploaded/;
location ~* \.(?:html|js|jpg|jpeg|gif|png|css|tgz|gz|rar|bz2|doc|pdf|ppt|tar|wav|bmp|ttf|rtf|swf|ico|flv|txt|woff|woff2|svg|xml)$ {
gzip_static always;
expires 30d;
access_log off;
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
}
}
location / {
# Using a variable is a trick to let Nginx start even if upstream host is not up yet
# (see https://sandro-keil.de/blog/2017/07/24/let-nginx-start-if-upstream-host-is-unavailable-or-down/)
set $upstream django:8000;
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, OPTIONS";
add_header Access-Control-Allow-Headers "Authorization, Content-Type, Accept";
add_header Access-Control-Allow-Credentials true;
add_header Content-Length 0;
add_header Content-Type text/plain;
add_header Access-Control-Max-Age 1728000;
return 200;
}
add_header Access-Control-Allow-Credentials false;
add_header Access-Control-Allow-Headers "Content-Type, Accept, Authorization, Origin, User-Agent";
add_header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, OPTIONS";
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_pass http://$upstream;
# uwsgi_params
include /etc/nginx/uwsgi_params;
location ~* \.(?:js|jpg|jpeg|gif|png|tgz|gz|rar|bz2|doc|pdf|ppt|tar|wav|bmp|ttf|rtf|swf|ico|flv|woff|woff2|svg|xml)$ {
gzip_static always;
expires 30d;
access_log off;
add_header Pragma "public";
add_header Cache-Control "max-age=31536000, public";
}
}
+39
View File
@@ -0,0 +1,39 @@
# NOTE : $VARIABLES are env variables replaced by entrypoint.sh using envsubst
# not to be mistaken for nginx variables (also starting with $, but usually lowercase)
worker_processes auto;
events {
}
http {
server_names_hash_bucket_size 64;
# Allow Nginx to resolve Docker host names (see https://sandro-keil.de/blog/2017/07/24/let-nginx-start-if-upstream-host-is-unavailable-or-down/)
resolver $RESOLVER; # it seems rancher uses 169.254.169.250 instead of 127.0.0.11 which works well in docker-compose (see /etc/resolv.conf)
# https - listens on specific name - this uses letsencrypt cert
# this includes a symlink that links either to nginx.https.available.conf if https in enabled
# or to an empty file if https is disabled.
include nginx.https.enabled.conf;
# http - listens to specific HTTP_HOST only - this is not encrypted (not ideal but admissible on LAN for instance)
# even if not used (HTTP_HOST empty), we must keep it as it's used for internal API calls between django and geoserver
# TODO : do not use unencrypted connection even on LAN, but is it possible to have browser not complaining about unknown authority ?
server {
listen 80;
server_name $HTTP_HOST 127.0.0.1 geonode;
include sites-enabled/*.conf;
}
# Default server closes the connection (we can connect use only HTTP_HOST and HTTPS HOST)
server {
listen 80 default_server;
listen 443;
server_name _;
return 444;
}
}
@@ -0,0 +1,37 @@
# NOTE : $VARIABLES are env variables replaced by entrypoint.sh using envsubst
# not to be mistaken for nginx variables (also starting with $, but usually lowercase)
# This file is to be included in the main nginx.conf configuration if HTTPS_HOST is set
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# this is the actual HTTPS host
server {
listen 443 ssl;
server_name $HTTPS_HOST;
keepalive_timeout 70;
ssl_certificate /certificate_symlink/fullchain.pem;
ssl_certificate_key /certificate_symlink/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
include sites-enabled/*.conf;
}
# if we try to connect from http, we redirect to https
server {
listen 80;
server_name $HTTPS_HOST $HTTP_HOST; # TODO : once geoserver supports relative urls, we should allow access though both HTTP and HTTPS at the same time and hence remove HTTP_HOST from this line
# Except for let's encrypt challenge
location /.well-known {
alias /geonode-certificates/.well-known;
include /etc/nginx/mime.types;
}
# Redirect to https
location / {
return 302 https://$HTTPS_HOST$request_uri; # TODO : we should use 301 (permanent redirect, but not practical for debug)
}
}
Executable
+69
View File
@@ -0,0 +1,69 @@
#!/bin/bash
set -e
/usr/local/bin/invoke update >> /usr/src/haitidata/invoke.log
source $HOME/.bashrc
source $HOME/.override_env
echo DATABASE_URL=$DATABASE_URL
echo GEODATABASE_URL=$GEODATABASE_URL
echo SITEURL=$SITEURL
echo ALLOWED_HOSTS=$ALLOWED_HOSTS
echo GEOSERVER_PUBLIC_LOCATION=$GEOSERVER_PUBLIC_LOCATION
echo MONITORING_ENABLED=$MONITORING_ENABLED
echo MONITORING_HOST_NAME=$MONITORING_HOST_NAME
echo MONITORING_SERVICE_NAME=$MONITORING_SERVICE_NAME
echo MONITORING_DATA_TTL=$MONITORING_DATA_TTL
/usr/local/bin/invoke waitfordbs >> /usr/src/haitidata/invoke.log
echo "waitfordbs task done"
echo "running migrations"
/usr/local/bin/invoke migrations >> /usr/src/haitidata/invoke.log
echo "migrations task done"
cmd="$@"
echo DOCKER_ENV=$DOCKER_ENV
if [ -z ${DOCKER_ENV} ] || [ ${DOCKER_ENV} = "development" ]
then
echo "Executing standard Django server $cmd for Development"
else
if [ ${IS_CELERY} = "true" ] || [ ${IS_CELERY} = "True" ]
then
cmd=$CELERY_CMD
echo "Executing Celery server $cmd for Production"
else
/usr/local/bin/invoke prepare >> /usr/src/haitidata/invoke.log
echo "prepare task done"
if [ ${IS_FIRST_START} = "true" ] || [ ${IS_FIRST_START} = "True" ] || [ ${FORCE_REINIT} = "true" ] || [ ${FORCE_REINIT} = "True" ] || [ ! -e "/mnt/volumes/statics/geonode_init.lock" ]; then
/usr/local/bin/invoke updategeoip >> /usr/src/haitidata/invoke.log
echo "updategeoip task done"
/usr/local/bin/invoke fixtures >> /usr/src/haitidata/invoke.log
echo "fixture task done"
/usr/local/bin/invoke monitoringfixture >> /usr/src/haitidata/invoke.log
echo "monitoringfixture task done"
/usr/local/bin/invoke initialized >> /usr/src/haitidata/invoke.log
echo "initialized"
fi
echo "refresh static data"
/usr/local/bin/invoke statics >> /usr/src/haitidata/invoke.log
echo "static data refreshed"
/usr/local/bin/invoke waitforgeoserver >> /usr/src/haitidata/invoke.log
echo "waitforgeoserver task done"
/usr/local/bin/invoke geoserverfixture >> /usr/src/haitidata/invoke.log
echo "geoserverfixture task done"
/usr/local/bin/invoke updateadmin >> /usr/src/haitidata/invoke.log
echo "updateadmin task done"
cmd=$UWSGI_CMD
echo "Executing UWSGI server $cmd for Production"
fi
fi
echo 'got command ${cmd}'
exec $cmd
View File
Whitespace-only changes.
-3
View File
@@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.
-25
View File
@@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('base', '24_to_26'),
]
operations = [
migrations.CreateModel(
name='RegionBBox',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('bbox_x0', models.DecimalField(null=True, max_digits=19, decimal_places=10, blank=True)),
('bbox_x1', models.DecimalField(null=True, max_digits=19, decimal_places=10, blank=True)),
('bbox_y0', models.DecimalField(null=True, max_digits=19, decimal_places=10, blank=True)),
('bbox_y1', models.DecimalField(null=True, max_digits=19, decimal_places=10, blank=True)),
('region', models.OneToOneField(to='base.Region')),
],
),
]
-19
View File
@@ -1,19 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('filter', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='regionbbox',
name='srid',
field=models.CharField(default=b'EPSG:4326', max_length=255),
),
]
View File
Whitespace-only changes.
-12
View File
@@ -1,12 +0,0 @@
from django.db import models
from geonode.base.models import Region
class RegionBBox(models.Model):
region = models.OneToOneField(Region, on_delete=models.CASCADE)
bbox_x0 = models.DecimalField(max_digits=19, decimal_places=10, blank=True, null=True)
bbox_x1 = models.DecimalField(max_digits=19, decimal_places=10, blank=True, null=True)
bbox_y0 = models.DecimalField(max_digits=19, decimal_places=10, blank=True, null=True)
bbox_y1 = models.DecimalField(max_digits=19, decimal_places=10, blank=True, null=True)
srid = models.CharField(max_length=255, default='EPSG:4326')
-86
View File
@@ -1,86 +0,0 @@
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from geonode.api.resourcebase_api import CommonModelApi, CommonMetaApi
from geonode.layers.models import Layer
from geonode.base.models import Region
class CommonModelApiExt(CommonModelApi):
def apply_filters(self, request, applicable_filters):
types = applicable_filters.pop('type', None)
extent = applicable_filters.pop('extent', None)
keywords = applicable_filters.pop('keywords__slug__in', None)
region = applicable_filters.get('regions__name__in', None)
region_bbox = None
if region:
print('region is ', region)
try:
region_obj = Region.objects.get(name=region[0])
except Region.DoesNotExist:
print 'it does not exists'
else:
print('db record', region_obj.name_en)
try:
regionbbox_obj = region_obj.regionbbox
except ObjectDoesNotExist:
print 'regionbbox does not exist'
else:
print(str(regionbbox_obj.bbox_x0))
bbox = [regionbbox_obj.bbox_x0, regionbbox_obj.bbox_y0, regionbbox_obj.bbox_x1, regionbbox_obj.bbox_y1]
bbox_valid = not any(coo is None for coo in bbox)
if bbox_valid:
region_bbox = ','.join([str(coo) for coo in bbox])
del applicable_filters['regions__name__in']
extent = None
print region_bbox
else:
print 'bbox not valid'
semi_filtered = super(
CommonModelApi,
self).apply_filters(
request,
applicable_filters)
filtered = None
if types:
for the_type in types:
if the_type in LAYER_SUBTYPES.keys():
if filtered:
filtered = filtered | semi_filtered.filter(
Layer___storeType=LAYER_SUBTYPES[the_type])
else:
filtered = semi_filtered.filter(
Layer___storeType=LAYER_SUBTYPES[the_type])
else:
if filtered:
filtered = filtered | semi_filtered.instance_of(
FILTER_TYPES[the_type])
else:
filtered = semi_filtered.instance_of(
FILTER_TYPES[the_type])
else:
filtered = semi_filtered
if extent:
filtered = self.filter_bbox(filtered, extent)
if keywords:
filtered = self.filter_h_keywords(filtered, keywords)
if region_bbox:
filtered = self.filter_bbox(filtered, region_bbox)
print 'filtering by bbox: ', region_bbox
return filtered
class LayerExtResource(CommonModelApiExt):
"""Layer Ext API"""
class Meta(CommonMetaApi):
queryset = Layer.objects.distinct().order_by('-date')
if settings.RESOURCE_PUBLISHING:
queryset = queryset.filter(is_published=True)
resource_name = 'layers'
excludes = ['csw_anytext', 'metadata_xml']
-3
View File
@@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.
-9
View File
@@ -1,9 +0,0 @@
from tastypie.api import Api
#from geonode.api.resourcebase_api import LayerResource
from filter.resourcebase_api import LayerExtResource
api_ext = Api(api_name='api')
api_ext.register(LayerExtResource())
-3
View File
@@ -1,3 +0,0 @@
from django.shortcuts import render
# Create your views here.
+11
View File
@@ -0,0 +1,11 @@
[
{
"fields": {
"user": 1000,
"key": "pyxW5djJ7XsjeFUXduAsGpR4xMGUwpeBGQRqTeT3",
"created": "2018-06-28T14:54:51Z"
},
"model": "tastypie.apikey",
"pk": 1
}
]
+21
View File
@@ -0,0 +1,21 @@
[
{
"model": "oauth2_provider.application",
"pk": 1001,
"fields": {
"skip_authorization": true,
"created": "2018-05-31T10:00:31.661Z",
"updated": "2018-05-31T11:30:31.245Z",
"algorithm": "RS256",
"redirect_uris": "http://localhost:8080/geoserver/index.html\nhttp://localhost/geoserver/index.html",
"name": "GeoServer",
"authorization_grant_type": "authorization-code",
"client_type": "confidential",
"client_id": "Jrchz2oPY3akmzndmgUTYrs9gczlgoV20YPSvqaV",
"client_secret": "rCnp5txobUo83EpQEblM8fVj3QT5zb5qRfxNsuPzCqZaiRyIoxM4jdgMiZKFfePBHYXCLd7B8NlkfDBY9HKeIQPcy5Cp08KQNpRHQbjpLItDHv12GvkSeXp6OxaUETv3",
"user": [
"admin"
]
}
}
]
+21
View File
@@ -0,0 +1,21 @@
[
{
"model": "oauth2_provider.application",
"pk": 1001,
"fields": {
"skip_authorization": true,
"created": "2018-05-31T10:00:31.661Z",
"updated": "2018-05-31T11:30:31.245Z",
"algorithm": "RS256",
"redirect_uris": "http://geonode/geoserver",
"name": "GeoServer",
"authorization_grant_type": "authorization-code",
"client_type": "confidential",
"client_id": "Jrchz2oPY3akmzndmgUTYrs9gczlgoV20YPSvqaV",
"client_secret": "rCnp5txobUo83EpQEblM8fVj3QT5zb5qRfxNsuPzCqZaiRyIoxM4jdgMiZKFfePBHYXCLd7B8NlkfDBY9HKeIQPcy5Cp08KQNpRHQbjpLItDHv12GvkSeXp6OxaUETv3",
"user": [
"admin"
]
}
}
]
File diff suppressed because it is too large. Load diff
+18
View File
@@ -0,0 +1,18 @@
[{
"fields": {
"date_joined": "2011-06-09 15:15:27",
"email": "ad@m.in",
"first_name": "",
"groups": [],
"is_active": true,
"is_staff": true,
"is_superuser": true,
"last_login": "2011-06-09 15:45:34",
"last_name": "",
"password": "pbkdf2_sha256$30000$rjuGt0Obn8on$cxF75frIOSaitNklLZ0IJ/VonUW0fwEFVF96o0M+lGc=",
"user_permissions": [],
"username": "admin"
},
"model": "people.Profile",
"pk": 1000
}]
+10
View File
@@ -0,0 +1,10 @@
[
{
"fields": {
"domain": "example.com",
"name": "example.com"
},
"model": "sites.site",
"pk": 1
}
]
-96
View File
@@ -1,96 +0,0 @@
Metadata-Version: 1.1
Name: haitidata
Version: 0.2
Summary: haitidata, based on GeoNode
Home-page: https://github.com/haitidata/haitidata
Author: UNKNOWN
Author-email: UNKNOWN
License: BSD
Description: Haitidata
========================
You should write some docs, it's good for the soul.
Installation
------------
Install geonode with::
$ sudo add-apt-repository ppa:geonode/stable
$ sudo apt-get update
$ sudo apt-get install geonode
Create a new template based on the geonode example project.::
$ django-admin startproject my_geonode --template=https://github.com/GeoNode/geonode-project/archive/2.6.zip -epy,rst
$ sudo pip install -e my_geonode
.. note:: You should NOT use the name geonode for your project as it will conflict with the default geonode package name.
Usage
-----
Rename the local_settings.py.sample to local_settings.py and edit it's content by setting the SITEURL and SITENAME.
Edit the file /etc/apache2/sites-available/geonode and change the following directive from:
WSGIScriptAlias / /var/www/geonode/wsgi/geonode.wsgi
to:
WSGIScriptAlias / /path/to/my_geonode/my_geonode/wsgi.py
To avoid having to grant apache permissions (i.e. www-data user and group) to your home dir where you likely setup the geonode-project; you may want to instead copy the wsgi.py file next to geonode.wsgi and replace the file name instead of the entire path.
$ cp /path/to/my_geonode/my_geonode/wsgi.py /var/www/geonode/wsgi/wsgi.py
Add the "Directory" directive for your folder like the following example:
<Directory "/home/vagrant/my_geonode/my_geonode/">
Order allow,deny
Options Indexes FollowSymLinks
Allow from all
Require all granted
IndexOptions FancyIndexing
</Directory>
Restart apache::
$ sudo service apache2 restart
Edit the templates in my_geonode/templates, the css and images to match your needs.
In the my_geonode folder run::
$ python manage.py collectstatic
Github Considerations
------------------------
While it is helpful to recommit your django project wrapper back to a distributed version control repository.
* It is also important to remember that production instances will store security information in the local_settings.py
* Admin/Devs should always remember to exclude this file in the .gitignore file in the same folder as the .git::
$ nano .gitignore
/{project}/local_settings.py
save, make sure the file is also removed from git cache::
$ git rm -f --cache //local_settings.py
$ git status
confirm the file is no longer staged for the next commit or that if it is as "removed"
Keywords: haitidata geonode django
Platform: UNKNOWN
Classifier: Development Status :: 1 - Planning
-11
View File
@@ -1,11 +0,0 @@
README.rst
haitidata/__init__.py
haitidata/settings.py
haitidata/urls.py
haitidata/wsgi.py
haitidata.egg-info/PKG-INFO
haitidata.egg-info/SOURCES.txt
haitidata.egg-info/dependency_links.txt
haitidata.egg-info/not-zip-safe
haitidata.egg-info/requires.txt
haitidata.egg-info/top_level.txt
-1
View File
@@ -1 +0,0 @@
-1
View File
@@ -1 +0,0 @@
-1
View File
@@ -1 +0,0 @@
django-tastypie==0.13.0
-1
View File
@@ -1 +0,0 @@
haitidata
+31
View File
@@ -0,0 +1,31 @@
# -*- 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/>.
#
#########################################################################
import os
__version__ = (2, 10, 1, 'final', 0)
default_app_config = "haitidata.apps.AppConfig"
def get_version():
import haitidata.version
return haitidata.version.get_version(__version__)
+38
View File
@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
#########################################################################
#
# Copyright (C) 2018 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.apps import AppConfig as BaseAppConfig
def run_setup_hooks(*args, **kwargs):
from django.conf import settings
from .celeryapp import app as celeryapp
if celeryapp not in settings.INSTALLED_APPS:
settings.INSTALLED_APPS += (celeryapp, )
class AppConfig(BaseAppConfig):
name = "haitidata"
label = "haitidata"
def ready(self):
super(AppConfig, self).ready()
run_setup_hooks()
+38
View File
@@ -0,0 +1,38 @@
# -*- 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 __future__ import absolute_import
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'haitidata.settings')
app = Celery('haitidata')
# Using a string here means the worker will not have to
# pickle the object when using Windows.
app.config_from_object('django.conf:settings', namespace="CELERY")
app.autodiscover_tasks()
@app.task(bind=True)
def debug_task(self):
print("Request: {!r}".format(self.request))
File renamed without changes.
Whitespace-only changes.
@@ -1,5 +0,0 @@
from django.conf import settings # import the settings file
def project_setting(request):
return {'GEOSERVER_BASE_URL': settings.GEOSERVER_BASE_URL}
+641
View File
@@ -0,0 +1,641 @@
# -*- coding: utf-8 -*-
#########################################################################
#
# Copyright (C) 2018 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/>.
#
#########################################################################
""" There are 3 ways to override GeoNode settings:
1. Using environment variables, if your changes to GeoNode are minimal.
2. Creating a downstream project, if you are doing a lot of customization.
3. Override settings in a local_settings.py file, legacy.
"""
import ast
import os
from urlparse import urlparse, urlunparse
from geonode.settings import *
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
MEDIA_ROOT = os.getenv('MEDIA_ROOT', os.path.join(PROJECT_ROOT, "uploaded"))
STATIC_ROOT = os.getenv('STATIC_ROOT',
os.path.join(PROJECT_ROOT, "static_root")
)
# SECRET_KEY = '************************'
# Make this unique, and don't share it with anybody.
SECRET_KEY = os.getenv('SECRET_KEY', "n(v@vf2rm!zcxaxey9(6ymhwayxnqzhlr)-f#$jkzt&2)way#*")
# per-deployment settings should go here
SITE_HOST_NAME = os.getenv('SITE_HOST_NAME', 'localhost')
SITE_HOST_PORT = os.getenv('SITE_HOST_PORT', None)
_default_siteurl = "http://%s:%s/" % (SITE_HOST_NAME, SITE_HOST_PORT) if SITE_HOST_PORT else "http://%s/" % SITE_HOST_NAME
SITEURL = os.getenv('SITEURL', _default_siteurl)
# we need hostname for deployed
_surl = urlparse(SITEURL)
HOSTNAME = _surl.hostname
# add trailing slash to site url. geoserver url will be relative to this
if not SITEURL.endswith('/'):
SITEURL = '{}/'.format(SITEURL)
try:
# try to parse python notation, default in dockerized env
ALLOWED_HOSTS = ast.literal_eval(os.getenv('ALLOWED_HOSTS'))
except ValueError:
# fallback to regular list of values separated with misc chars
ALLOWED_HOSTS = [HOSTNAME, 'localhost', 'django', 'geonode'] if os.getenv('ALLOWED_HOSTS') is None \
else re.split(r' *[,|:|;] *', os.getenv('ALLOWED_HOSTS'))
TIME_ZONE = 'UTC'
# Login and logout urls override
LOGIN_URL = os.getenv('LOGIN_URL', '{}account/login/'.format(SITEURL))
LOGOUT_URL = os.getenv('LOGOUT_URL', '{}account/logout/'.format(SITEURL))
ACCOUNT_LOGIN_REDIRECT_URL = os.getenv('LOGIN_REDIRECT_URL', SITEURL)
ACCOUNT_LOGOUT_REDIRECT_URL = os.getenv('LOGOUT_REDIRECT_URL', SITEURL)
AVATAR_GRAVATAR_SSL = ast.literal_eval(os.getenv('AVATAR_GRAVATAR_SSL', 'True'))
# Backend
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'geonode',
'USER': 'geonode',
'PASSWORD': 'geonode',
'HOST': 'localhost',
'PORT': '5432',
'CONN_MAX_AGE': 5,
'CONN_TOUT': 5,
'OPTIONS': {
'connect_timeout': 5,
}
},
# vector datastore for uploads
'datastore': {
'ENGINE': 'django.contrib.gis.db.backends.postgis',
# 'ENGINE': '', # Empty ENGINE name disables
'NAME': 'geonode_data',
'USER': 'geonode',
'PASSWORD': 'geonode',
'HOST': 'localhost',
'PORT': '5432',
'CONN_MAX_AGE': 5,
'CONN_TOUT': 5,
'OPTIONS': {
'connect_timeout': 5,
}
}
}
GEOSERVER_LOCATION = os.getenv(
'GEOSERVER_LOCATION', 'http://localhost:8080/geoserver/'
)
GEOSERVER_PUBLIC_HOST = os.getenv(
'GEOSERVER_PUBLIC_HOST', SITE_HOST_NAME
)
GEOSERVER_PUBLIC_PORT = os.getenv(
'GEOSERVER_PUBLIC_PORT', 8080
)
_default_public_location = 'http://{}:{}/geoserver/'.format(GEOSERVER_PUBLIC_HOST, GEOSERVER_PUBLIC_PORT) if GEOSERVER_PUBLIC_PORT else 'http://{}/geoserver/'.format(GEOSERVER_PUBLIC_HOST)
GEOSERVER_WEB_UI_LOCATION = os.getenv(
'GEOSERVER_WEB_UI_LOCATION', GEOSERVER_LOCATION
)
GEOSERVER_PUBLIC_LOCATION = os.getenv(
'GEOSERVER_PUBLIC_LOCATION', _default_public_location
)
OGC_SERVER_DEFAULT_USER = os.getenv(
'GEOSERVER_ADMIN_USER', 'admin'
)
OGC_SERVER_DEFAULT_PASSWORD = os.getenv(
'GEOSERVER_ADMIN_PASSWORD', 'geoserver'
)
# OGC (WMS/WFS/WCS) Server Settings
OGC_SERVER = {
'default': {
'BACKEND': 'geonode.geoserver',
'LOCATION': GEOSERVER_LOCATION,
'WEB_UI_LOCATION': GEOSERVER_WEB_UI_LOCATION,
'LOGIN_ENDPOINT': 'j_spring_oauth2_geonode_login',
'LOGOUT_ENDPOINT': 'j_spring_oauth2_geonode_logout',
# PUBLIC_LOCATION needs to be kept like this because in dev mode
# the proxy won't work and the integration tests will fail
# the entire block has to be overridden in the local_settings
'PUBLIC_LOCATION': GEOSERVER_PUBLIC_LOCATION,
'USER': OGC_SERVER_DEFAULT_USER,
'PASSWORD': OGC_SERVER_DEFAULT_PASSWORD,
'MAPFISH_PRINT_ENABLED': True,
'PRINT_NG_ENABLED': True,
'GEONODE_SECURITY_ENABLED': True,
'GEOFENCE_SECURITY_ENABLED': True,
'WMST_ENABLED': False,
'BACKEND_WRITE_ENABLED': True,
'WPS_ENABLED': False,
'LOG_FILE': '%s/geoserver/data/logs/geoserver.log' % os.path.abspath(os.path.join(PROJECT_ROOT, os.pardir)),
# Set to dictionary identifier of database containing spatial data in DATABASES dictionary to enable
'DATASTORE': 'datastore',
'TIMEOUT': int(os.getenv('OGC_REQUEST_TIMEOUT', '30')),
'MAX_RETRIES': int(os.getenv('OGC_REQUEST_MAX_RETRIES', '5')),
'BACKOFF_FACTOR': float(os.getenv('OGC_REQUEST_BACKOFF_FACTOR', '0.3')),
'POOL_MAXSIZE': int(os.getenv('OGC_REQUEST_POOL_MAXSIZE', '10')),
'POOL_CONNECTIONS': int(os.getenv('OGC_REQUEST_POOL_CONNECTIONS', '10')),
}
}
# If you want to enable Mosaics use the following configuration
UPLOADER = {
# 'BACKEND': 'geonode.rest',
'BACKEND': 'geonode.importer',
'OPTIONS': {
'TIME_ENABLED': True,
'MOSAIC_ENABLED': False,
},
'SUPPORTED_CRS': [
'EPSG:4326',
'EPSG:3785',
'EPSG:3857',
'EPSG:32647',
'EPSG:32736'
],
'SUPPORTED_EXT': [
'.shp',
'.csv',
'.kml',
'.kmz',
'.json',
'.geojson',
'.tif',
'.tiff',
'.geotiff',
'.gml',
'.xml'
]
}
# CSW settings
CATALOGUE = {
'default': {
# The underlying CSW implementation
# default is pycsw in local mode (tied directly to GeoNode Django DB)
'ENGINE': 'geonode.catalogue.backends.pycsw_local',
# pycsw in non-local mode
# 'ENGINE': 'geonode.catalogue.backends.pycsw_http',
# GeoNetwork opensource
# 'ENGINE': 'geonode.catalogue.backends.geonetwork',
# deegree and others
# 'ENGINE': 'geonode.catalogue.backends.generic',
# The FULLY QUALIFIED base url to the CSW instance for this GeoNode
'URL': urljoin(SITEURL, '/catalogue/csw'),
# 'URL': 'http://localhost:8080/geonetwork/srv/en/csw',
# 'URL': 'http://localhost:8080/deegree-csw-demo-3.0.4/services',
# login credentials (for GeoNetwork)
# 'USER': 'admin',
# 'PASSWORD': 'admin',
# 'ALTERNATES_ONLY': True,
}
}
# pycsw settings
PYCSW = {
# pycsw configuration
'CONFIGURATION': {
# uncomment / adjust to override server config system defaults
# 'server': {
# 'maxrecords': '10',
# 'pretty_print': 'true',
# 'federatedcatalogues': 'http://catalog.data.gov/csw'
# },
'server': {
'home': '.',
'url': CATALOGUE['default']['URL'],
'encoding': 'UTF-8',
'language': LANGUAGE_CODE,
'maxrecords': '20',
'pretty_print': 'true',
# 'domainquerytype': 'range',
'domaincounts': 'true',
'profiles': 'apiso,ebrim',
},
'manager': {
# authentication/authorization is handled by Django
'transactions': 'false',
'allowed_ips': '*',
# 'csw_harvest_pagesize': '10',
},
'metadata:main': {
'identification_title': 'GeoNode Catalogue',
'identification_abstract': 'GeoNode is an open source platform' \
' that facilitates the creation, sharing, and collaborative use' \
' of geospatial data',
'identification_keywords': 'sdi, catalogue, discovery, metadata,' \
' GeoNode',
'identification_keywords_type': 'theme',
'identification_fees': 'None',
'identification_accessconstraints': 'None',
'provider_name': 'Organization Name',
'provider_url': SITEURL,
'contact_name': 'Lastname, Firstname',
'contact_position': 'Position Title',
'contact_address': 'Mailing Address',
'contact_city': 'City',
'contact_stateorprovince': 'Administrative Area',
'contact_postalcode': 'Zip or Postal Code',
'contact_country': 'Country',
'contact_phone': '+xx-xxx-xxx-xxxx',
'contact_fax': '+xx-xxx-xxx-xxxx',
'contact_email': 'Email Address',
'contact_url': 'Contact URL',
'contact_hours': 'Hours of Service',
'contact_instructions': 'During hours of service. Off on ' \
'weekends.',
'contact_role': 'pointOfContact',
},
'metadata:inspire': {
'enabled': 'true',
'languages_supported': 'eng,gre',
'default_language': 'eng',
'date': 'YYYY-MM-DD',
'gemet_keywords': 'Utility and governmental services',
'conformity_service': 'notEvaluated',
'contact_name': 'Organization Name',
'contact_email': 'Email Address',
'temp_extent': 'YYYY-MM-DD/YYYY-MM-DD',
}
}
}
# -- START Client Hooksets Setup
# GeoNode javascript client configuration
# default map projection
# Note: If set to EPSG:4326, then only EPSG:4326 basemaps will work.
DEFAULT_MAP_CRS = os.environ.get('DEFAULT_MAP_CRS', "EPSG:3857")
DEFAULT_LAYER_FORMAT = os.environ.get('DEFAULT_LAYER_FORMAT', "image/png8")
# Where should newly created maps be focused?
DEFAULT_MAP_CENTER = (os.environ.get('DEFAULT_MAP_CENTER_X', 0), os.environ.get('DEFAULT_MAP_CENTER_Y', 0))
# How tightly zoomed should newly created maps be?
# 0 = entire world;
# maximum zoom is between 12 and 15 (for Google Maps, coverage varies by area)
DEFAULT_MAP_ZOOM = int(os.environ.get('DEFAULT_MAP_ZOOM', 3))
MAPBOX_ACCESS_TOKEN = os.environ.get('MAPBOX_ACCESS_TOKEN', None)
BING_API_KEY = os.environ.get('BING_API_KEY', None)
GOOGLE_API_KEY = os.environ.get('GOOGLE_API_KEY', None)
GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY = os.getenv('GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY', 'mapstore')
MAP_BASELAYERS = [{}]
"""
To enable the REACT based Client:
1. pip install pip install django-geonode-client==1.0.9
2. enable those:
"""
if GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY == 'react':
GEONODE_CLIENT_HOOKSET = os.getenv('GEONODE_CLIENT_HOOKSET', 'geonode.client.hooksets.ReactHookSet')
if 'geonode-client' not in INSTALLED_APPS:
INSTALLED_APPS += ('geonode-client', )
"""
To enable the Leaflet based Client:
1. enable those:
"""
if GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY == 'leaflet':
GEONODE_CLIENT_HOOKSET = os.getenv('GEONODE_CLIENT_HOOKSET', 'geonode.client.hooksets.LeafletHookSet')
LEAFLET_CONFIG = {
'TILES': [
# Find tiles at:
# http://leaflet-extras.github.io/leaflet-providers/preview/
# Stamen toner lite.
('Watercolor',
'http://{s}.tile.stamen.com/watercolor/{z}/{x}/{y}.png',
'Map tiles by <a href="http://stamen.com">Stamen Design</a>, \
<a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> \
&mdash; Map data &copy; \
<a href="http://openstreetmap.org">OpenStreetMap</a> contributors, \
<a href="http://creativecommons.org/licenses/by-sa/2.0/"> \
CC-BY-SA</a>'),
('Toner Lite',
'http://{s}.tile.stamen.com/toner-lite/{z}/{x}/{y}.png',
'Map tiles by <a href="http://stamen.com">Stamen Design</a>, \
<a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> \
&mdash; Map data &copy; \
<a href="http://openstreetmap.org">OpenStreetMap</a> contributors, \
<a href="http://creativecommons.org/licenses/by-sa/2.0/"> \
CC-BY-SA</a>'),
],
'PLUGINS': {
'esri-leaflet': {
'js': 'lib/js/leaflet.js',
'auto-include': True,
},
'leaflet-fullscreen': {
'css': 'lib/css/leaflet.fullscreen.css',
'js': 'lib/js/Leaflet.fullscreen.min.js',
'auto-include': True,
},
'leaflet-opacity': {
'css': 'lib/css/L.Control.Opacity.css',
'js': 'lib/js/L.Control.Opacity.js',
'auto-include': True,
},
'leaflet-navbar': {
'css': 'lib/css/Leaflet.NavBar.css',
'js': 'lib/js/index.js',
'auto-include': True,
},
'leaflet-measure': {
'css': 'lib/css/leaflet-measure.css',
'js': 'lib/js/leaflet-measure.js',
'auto-include': True,
},
},
'SRID': 3857,
'RESET_VIEW': False
}
if not DEBUG_STATIC:
# if not DEBUG_STATIC, use minified css and js
LEAFLET_CONFIG['PLUGINS'] = {
'leaflet-plugins': {
'js': 'lib/js/leaflet-plugins.min.js',
'css': 'lib/css/leaflet-plugins.min.css',
'auto-include': True,
}
}
"""
To enable the MapStore2 REACT based Client:
1. pip install pip install django-geonode-mapstore-client==1.0
2. enable those:
"""
if GEONODE_CLIENT_LAYER_PREVIEW_LIBRARY == 'mapstore':
GEONODE_CLIENT_HOOKSET = os.getenv('GEONODE_CLIENT_HOOKSET', 'geonode_mapstore_client.hooksets.MapStoreHookSet')
if 'geonode_mapstore_client' not in INSTALLED_APPS:
INSTALLED_APPS += (
'mapstore2_adapter',
'geonode_mapstore_client',)
# This must be set to True in case you run the client in DEBUG mode with `npm run start`
MAPSTORE_DEBUG = False
def get_geonode_catalogue_service():
if PYCSW:
pycsw_config = PYCSW["CONFIGURATION"]
if pycsw_config:
pycsw_catalogue = {
("%s" % pycsw_config['metadata:main']['identification_title']): {
"url": CATALOGUE['default']['URL'],
"type": "csw",
"title": pycsw_config['metadata:main']['identification_title'],
"autoload": True
}
}
return pycsw_catalogue
return None
GEONODE_CATALOGUE_SERVICE = get_geonode_catalogue_service()
MAPSTORE_CATALOGUE_SERVICES = {
"Demo WMS Service": {
"url": "https://demo.geo-solutions.it/geoserver/wms",
"type": "wms",
"title": "Demo WMS Service",
"autoload": False
},
"Demo WMTS Service": {
"url": "https://demo.geo-solutions.it/geoserver/gwc/service/wmts",
"type": "wmts",
"title": "Demo WMTS Service",
"autoload": False
}
}
MAPSTORE_CATALOGUE_SELECTED_SERVICE = "Demo WMS Service"
if GEONODE_CATALOGUE_SERVICE:
MAPSTORE_CATALOGUE_SERVICES[list(GEONODE_CATALOGUE_SERVICE.keys())[0]] = GEONODE_CATALOGUE_SERVICE[list(GEONODE_CATALOGUE_SERVICE.keys())[0]]
MAPSTORE_CATALOGUE_SELECTED_SERVICE = list(GEONODE_CATALOGUE_SERVICE.keys())[0]
DEFAULT_MS2_BACKGROUNDS = [
{
"type": "tileprovider",
"title": "Stamen Watercolor",
"provider": "Stamen.Watercolor",
"name": "Stamen.Watercolor",
"source": "Stamen",
"group": "background",
"thumbURL": "https://stamen-tiles-c.a.ssl.fastly.net/watercolor/0/0/0.jpg",
"visibility": False
},
{
"type": "tileprovider",
"title": "Stamen Terrain",
"provider": "Stamen.Terrain",
"name": "Stamen.Terrain",
"source": "Stamen",
"group": "background",
"thumbURL": "https://stamen-tiles-d.a.ssl.fastly.net/terrain/0/0/0.png",
"visibility": False
},
{
"type": "tileprovider",
"title": "Stamen Toner",
"provider": "Stamen.Toner",
"name": "Stamen.Toner",
"source": "Stamen",
"group": "background",
"thumbURL": "https://stamen-tiles-d.a.ssl.fastly.net/toner/0/0/0.png",
"visibility": False
},
{
"type": "osm",
"title": "Open Street Map",
"name": "mapnik",
"source": "osm",
"group": "background",
"visibility": True
},
{
"type": "tileprovider",
"title": "OpenTopoMap",
"provider": "OpenTopoMap",
"name": "OpenTopoMap",
"source": "OpenTopoMap",
"group": "background",
"visibility": False
},
{
"type": "wms",
"title": "Sentinel-2 cloudless - https://s2maps.eu",
"format": "image/jpeg",
"id": "s2cloudless",
"name": "s2cloudless:s2cloudless",
"url": "https://maps.geo-solutions.it/geoserver/wms",
"group": "background",
"thumbURL": "%sstatic/mapstorestyle/img/s2cloudless-s2cloudless.png" % SITEURL,
"visibility": False
},
{
"source": "ol",
"group": "background",
"id": "none",
"name": "empty",
"title": "Empty Background",
"type": "empty",
"visibility": False,
"args": ["Empty Background", {"visibility": False}]
}
]
if MAPBOX_ACCESS_TOKEN:
MAPBOX_BASEMAPS = {
"type": "tileprovider",
"title": "MapBox streets-v11",
"provider": "MapBoxStyle",
"name": "MapBox streets-v11",
"accessToken": "%s" % MAPBOX_ACCESS_TOKEN,
"source": "streets-v11",
"thumbURL": "https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/256/6/33/23?access_token=%s" % MAPBOX_ACCESS_TOKEN,
"group": "background",
"visibility": True
}
DEFAULT_MS2_BACKGROUNDS = [MAPBOX_BASEMAPS,] + DEFAULT_MS2_BACKGROUNDS
if BING_API_KEY:
BING_BASEMAPS = [
{
"type": "bing",
"title": "Bing Aerial",
"name": "AerialWithLabels",
"source": "bing",
"group": "background",
"apiKey": "",
"visibility": True
},
{
"type": "bing",
"title": "Bing RoadOnDemand",
"name": "RoadOnDemand",
"source": "bing",
"group": "background",
"apiKey": "",
"thumbURL": "%sstatic/mapstorestyle/img/bing_road_on_demand.png" % SITEURL,
"visibility": False
},
{
"type": "bing",
"title": "Bing AerialWithLabelsOnDemand",
"name": "AerialWithLabelsOnDemand",
"source": "bing",
"group": "background",
"apiKey": "",
"thumbURL": "%sstatic/mapstorestyle/img/bing_aerial_w_labels.png" % SITEURL,
"visibility": False
},
{
"type": "bing",
"title": "Bing CanvasDark",
"name": "CanvasDark",
"source": "bing",
"group": "background",
"apiKey": "",
"thumbURL": "%sstatic/mapstorestyle/img/bing_canvas_dark.png" % SITEURL,
"visibility": False
}
]
DEFAULT_MS2_BACKGROUNDS = [BING_BASEMAPS, ] + DEFAULT_MS2_BACKGROUNDS
MAPSTORE_BASELAYERS = DEFAULT_MS2_BACKGROUNDS
# -- END Client Hooksets Setup
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(process)d '
'%(thread)d %(message)s'
},
'simple': {
'format': '%(message)s',
},
},
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler',
}
},
"loggers": {
"django": {
"handlers": ["console"], "level": "ERROR", },
"geonode": {
"handlers": ["console"], "level": "INFO", },
"geonode.qgis_server": {
"handlers": ["console"], "level": "ERROR", },
"geoserver-restconfig.catalog": {
"handlers": ["console"], "level": "ERROR", },
"owslib": {
"handlers": ["console"], "level": "ERROR", },
"pycsw": {
"handlers": ["console"], "level": "INFO", },
"celery": {
'handlers': ["console"], 'level': 'ERROR', },
},
}
# Additional settings
# X_FRAME_OPTIONS = 'ALLOW-FROM %s' % SITEURL
CORS_ORIGIN_ALLOW_ALL = True
GEOIP_PATH = "/usr/local/share/GeoIP"
Binary file not shown.
+1 -1
View File
@@ -1333,7 +1333,7 @@ msgstr "Risques et Aléa en Haïti"
#: haitidata/templates/site_index.html:22
msgid "River Flood"
msgstr "Inondation Riverine"
msgstr "Inondation Riveraine"
#: haitidata/templates/site_index.html:26
msgid "Cyclone"
+27 -182
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
#########################################################################
#
# Copyright (C) 2012 OpenPlans
# 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
@@ -19,210 +19,55 @@
#########################################################################
# Django settings for the GeoNode project.
import ast
import os
from geonode.settings import *
from urlparse import urlparse, urlunparse
# Load more settings from a file called local_settings.py if it exists
try:
from haitidata.local_settings import *
# from geonode.local_settings import *
except ImportError:
from geonode.settings import *
from .utils import absolute_path
#
# General Django development settings
#
PROJECT_NAME = 'haitidata'
SITENAME = 'haitidata'
# add trailing slash to site url. geoserver url will be relative to this
if not SITEURL.endswith('/'):
SITEURL = '{}/'.format(SITEURL)
TIME_ZONE = os.getenv('TIME_ZONE', "America/Port-au-Prince")
SITENAME = os.getenv("SITENAME", 'haitidata')
# Defines the directory that contains the settings file as the LOCAL_ROOT
# It is used for relative settings elsewhere.
LOCAL_ROOT = os.path.abspath(os.path.dirname(__file__))
WSGI_APPLICATION = "haitidata.wsgi.application"
WSGI_APPLICATION = "{}.wsgi.application".format(PROJECT_NAME)
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = os.getenv('LANGUAGE_CODE', "en")
# Load more settings from a file called local_settings.py if it exists
try:
from local_settings import *
except ImportError:
pass
if PROJECT_NAME not in INSTALLED_APPS:
INSTALLED_APPS += (PROJECT_NAME,)
# Location of url mappings
ROOT_URLCONF = os.getenv('ROOT_URLCONF', '{}.urls'.format(PROJECT_NAME))
# Additional directories which hold static files
STATICFILES_DIRS.append(
os.path.join(LOCAL_ROOT, "static"),
)
CLIPPED_DIRECTORY = absolute_path('base', 'clipped_geotiff')
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(PROJECT_ROOT, "templates")],
'APP_DIRS': False,
'OPTIONS': {
# List of callables that know how to import
# templates from various sources.
'loaders': [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
],
'context_processors': [
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.static",
"django.core.context_processors.media",
"django.core.context_processors.request",
"django.core.context_processors.tz",
'account.context_processors.account',
'geonode.context_processors.resource_urls',
"geonode.geoserver.context_processors.geoserver_urls",
"haitidata.context_processors.clipped_geotiff.clipped_geotiff",
],
},
},
]
# Location of url mappings
ROOT_URLCONF = 'haitidata.urls'
# Location of locale files
LOCALE_PATHS = (
os.path.join(LOCAL_ROOT, 'locale'),
os.path.join(PROJECT_ROOT, 'locale'),
) + LOCALE_PATHS
INSTALLED_APPS = INSTALLED_APPS + (
"django.contrib.redirects",
'haitidata',
'osgeo_importer',
'geonode-client',
'charts_app',
'wfs_harvest',
"clip-and-ship",
'filter',
'thumbnail'
)
GEOSERVER_PUBLIC_LOCATION = os.environ.get(
'GEOSERVER_PUBLIC_LOCATION', 'http://136.243.4.93:8080/geoserver/'
)
# dynamic setting based on domain
GEOSERVER_BASE_URL = os.environ.get(
'GEOSERVER_BASE_URL',
'http://136.243.4.93:8080/geoserver/'
) # change this to geoserver container location
LAYER_PREVIEW_LIBRARY = 'react'
TEMPLATES[0]['DIRS'].insert(0, os.path.join(LOCAL_ROOT, "templates"))
IMPORT_HANDLERS = [
# If GeoServer handlers are enabled, you must have an instance of geoserver running.
# Warning: the order of the handlers here matters.
'osgeo_importer.handlers.FieldConverterHandler',
'osgeo_importer.handlers.geoserver.GeoserverPublishHandler',
'osgeo_importer.handlers.geoserver.GeoserverPublishCoverageHandler',
'osgeo_importer.handlers.geoserver.GeoServerTimeHandler',
'osgeo_importer.handlers.geoserver.GeoWebCacheHandler',
'osgeo_importer.handlers.geoserver.GeoServerBoundsHandler',
'osgeo_importer.handlers.geoserver.GenericSLDHandler',
'osgeo_importer.handlers.geonode.GeoNodePublishHandler',
'osgeo_importer.handlers.mapproxy.publish_handler.MapProxyGPKGTilePublishHandler',
'osgeo_importer.handlers.geoserver.GeoServerStyleHandler',
'osgeo_importer.handlers.geonode.GeoNodeMetadataHandler'
]
OSGEO_DATASTORE = 'datastore'
OSGEO_IMPORTER_GEONODE_ENABLED = True
OSGEO_IMPORTER_VALID_EXTENSIONS = [
'shp', 'shx', 'prj', 'dbf', 'kml', 'geojson', 'json', 'tif', 'tiff',
'gpkg', 'csv', 'zip', 'xml', 'sld'
]
LOGGING['loggers']['osgeo_importer'] = {"handlers": ["console"], "level": "DEBUG"}
#DATABASE_ROUTERS = ['.dbrouters.DefaultOnlyMigrations']
# # === MapProxy settings
# # This is the location to place additional configuration files for mapproxy to work from.
# # Currently it is only to allow tiles from gpkg files to be served.
MAPPROXY_CONFIG_DIR = '/opt/geonode-mapproxy-config'
# Name of the mapproxy config file to create for tile gpkg files.
MAPPROXY_CONFIG_FILENAME = 'geonode.yaml'
# This is the base URL for MapProxy WMS services
# URLs will look like this: /geonode/tms/1.0.0/<layer_name>/<grid_name>/0/0/0.png and a <grid_name> will be
# set as '<layer_name>_<projection_id>' (by conf_from_geopackage()).
MAPPROXY_SERVER_LOCATION = 'http://localhost:8088/geonode/tms/1.0.0/{layer_name}/{grid_name}/'
#import pyproj
#PROJECTION_DIRECTORY = os.path.join(os.path.dirname(pyproj.__file__), 'data/')
PROJECTION_DIRECTORY = '/tmp/'
try:
CELERY_IMPORTS = CELERY_IMPORTS + ('osgeo_importer.tasks',)
except:
CELERY_IMPORTS = ('osgeo_importer.tasks',)
LOCKDOWN_GEONODE = True
BROKER_URL = "amqp://guest@localhost:5672"
CELERY_ALWAYS_EAGER = True
IMPORT_TASK_SOFT_TIME_LIMIT = 90
# Force French as default language
# Needs /usr/local/lib/python2.7/dist-packages/setmydefaultlanguage/__init__.py
# See doc http://docs.geonode.org/en/master/tutorials/admin/default_lang/
LANGUAGE_CODE = 'fr'
MIDDLEWARE_CLASSES += (
'setmydefaultlanguage.ForceDefaultLanguageMiddleware',
)
_HAITI_LANGUAGES = (
('en', 'English'),
('fr', 'Français'),
)
LANGUAGES = os.getenv('LANGUAGES', _HAITI_LANGUAGES)
# maximum clip size in bytes
MAXIMUM_CLIP_SIZE = '40000000'
SOCIAL_ORIGINS = [{
"label":"paper-plane-o",
"url":"mailto:?subject={name}&body={url}",
"css_class":"email"
}, {
"label":"facebook",
"url":"http://www.facebook.com/sharer.php?u={url}",
"css_class":"fb"
}, {
"label":"twitter",
"url":"https://twitter.com/share?url={url}&hashtags={hashtags}",
"css_class":"tw"
}, {
"label":"google-plus",
"url":"https://plus.google.com/share?url={url}",
"css_class":"gp"
}]
WCS_DOWNLOADED_RATIO_SIZE = 1
MAX_CSV_RECORDS = 20000
UPLOADER = {
'BACKEND': 'geonode.rest',
'OPTIONS': {
'TIME_ENABLED': False,
'MOSAIC_ENABLED': True,
'GEOGIG_ENABLED': False,
}
}
OFFICIAL_USERS = [
'cnigs', 'ciat', 'ihsi', 'dpc', 'marndr', 'mairie-de-pap', 'faculte-de-science', 'undp-haiti', 'idb',
'european-union', 'worldbank'
]
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
loaders = TEMPLATES[0]['OPTIONS'].get('loaders') or ['django.template.loaders.filesystem.Loader','django.template.loaders.app_directories.Loader']
# loaders.insert(0, 'apptemplates.Loader')
TEMPLATES[0]['OPTIONS']['loaders'] = loaders
TEMPLATES[0].pop('APP_DIRS', None)
Regular → Executable
+12
View File
@@ -1,8 +1,20 @@
# Introduction
This directory is used to store static assets for your project. User media files
(FileFields/ImageFields) are not stored here.
The convention for this directory is:
* css/ — stores CSS files
* less/ - stores LESS files
* js/ — stores Javascript files
* img/ — stores image files
# Gulp
Gulp can be used to automatically build css from LESS files. The gulp process will
watch you LESS files for changes and recompile. To install gulp do
the following 2 steps:
1. cd into the project directory and install dependencies with `npm install`
2. install gulp command line globally with `sudo npm install -g gulp`
-6723
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
-48
View File
@@ -1,48 +0,0 @@
.media {
margin-top: 15px;
}
.media:first-child {
margin-top: 0;
}
.media,
.media-body {
zoom: 1;
overflow: hidden;
}
.media-body {
width: 10000px;
}
.media-object {
display: block;
}
.media-object.img-thumbnail {
max-width: none;
}
.media-right,
.media > .pull-right {
padding-left: 10px;
}
.media-left,
.media > .pull-left {
padding-right: 10px;
}
.media-left,
.media-right,
.media-body {
display: table-cell;
vertical-align: top;
}
.media-middle {
vertical-align: middle;
}
.media-bottom {
vertical-align: bottom;
}
.media-heading {
margin-top: 0;
margin-bottom: 5px;
}
.media-list {
padding-left: 0;
list-style: none;
}
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Loaded 100 of 436 files, more files were not shown because too many files have changed in this diff. Show more