Skip to content
Commits on Source (2)
......@@ -59,4 +59,3 @@ trash.py
ClimbingAssoPortal/static-src/build/
root
static-src
\ No newline at end of file
......@@ -27,6 +27,7 @@
"react-bootstrap-slider": "^2.1.3",
"react-dom": "^16.3.0",
"react-intl": "^2.4.0",
"react-show": "^2.0.4",
"react-table": "^6.8.0",
"rxjs": "^5.5.8",
"select2": "^4.0.6-rc.1",
......
/**************************************************************************************************/
import React from 'react';
import { render } from 'react-dom';
import { IntlProvider, addLocaleData } from 'react-intl';
import en from 'react-intl/locale-data/en';
import fr from 'react-intl/locale-data/fr';
// import App from '...';
import localeData from './../../build/locales/data.json';
/**************************************************************************************************/
addLocaleData([...en, ...fr]);
// Define user's language. Different browsers have the user locale defined
// on different fields on the `navigator` object, so we make sure to account
// for these different by checking all of them
const language =
(navigator.languages && navigator.languages[0]) ||
navigator.language ||
navigator.userLanguage;
// Split locales with a region code
const languageWithoutRegionCode = language.toLowerCase().split(/[_-]+/)[0];
// Try full locale, try locale without region code, fallback to 'en'
const messages = localeData[languageWithoutRegionCode] || localeData[language] || localeData.en;
// Render our root component into the div with id "root"
// We select the messages to pass to IntlProvider based on the user's locale
render(
<IntlProvider locale={language} messages={messages}>
<App />
</IntlProvider>,
document.getElementById('root')
);
......@@ -53,69 +53,92 @@ ROOT_URLCONF = 'ClimbingAssoPortalSite.urls'
WSGI_APPLICATION = 'ClimbingAssoPortalSite.wsgi.application'
####################################################################################################
# USE_PROMETHEUS = True
USE_PROMETHEUS = False
####################################################################################################
#
# Application definition
#
# /!\ INSTALLED_APPS is an ordered list
INSTALLED_APPS = [
# /!\ ordered list
# http://django-suit.readthedocs.io/en/develop
'suit', # must be added before admin
# 'ClimbingAssoPortal.apps.SuitConfig', # custom suit v2 config
# http://django-suit.readthedocs.io/en/develop
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.gis', # https://docs.djangoproject.com/en/2.0/ref/contrib/gis/
'django.contrib.sites',
]
INSTALLED_APPS += [
'rest_framework', # http://www.django-rest-framework.org
'django_filters', # https://django-filter.readthedocs.io/en/latest
'rest_framework_gis', # https://github.com/djangonauts/django-rest-framework-gis
'rest_framework_swagger', # https://django-rest-swagger.readthedocs.io/en/latest
'drf_yasg', # https://drf-yasg.readthedocs.io/en/stable/
# used by DRF filter
'crispy_forms', # http://django-crispy-forms.readthedocs.io/en/latest/
'graphene_django', # http://docs.graphene-python.org/projects/django/en/latest
]
INSTALLED_APPS += [
# http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html#using-celery-with-django
'django_celery_results', # http://django-celery-results.readthedocs.io/en/latest/
'django_celery_beat', # http://django-celery-beat.readthedocs.io/en/latest/
]
INSTALLED_APPS += [
'health_check', # http://django-health-check.readthedocs.io/en/latest/index.html
'health_check.db', # stock Django health checkers
'health_check.cache',
'health_check.storage',
# 'health_check.contrib.celery', # requires celery
'health_check.contrib.psutil', # disk and memory utilization; requires psutil
]
if USE_PROMETHEUS:
INSTALLED_APPS.append('prometheus')
INSTALLED_APPS += [
'reversion', # https://django-reversion.readthedocs.io/en/stable
'django_jinja', # http://niwinz.github.io/django-jinja/latest
'bootstrapform', # https://github.com/tzangms/django-bootstrap-form
'django_filters', # https://django-filter.readthedocs.io/en/latest
'django_jinja', # http://niwinz.github.io/django-jinja/latest
'django_select2', # http://django-select2.readthedocs.io/en/latest
'bootstrapform', # https://github.com/tzangms/django-bootstrap-form
'crispy_forms', # http://django-crispy-forms.readthedocs.io/en/latest/ # used by DRF filter
# 'pinax_theme_bootstrap', # https://github.com/pinax/pinax-theme-bootstrap
'account', # http://django-user-accounts.readthedocs.io/en/latest
# https://django-filer.readthedocs.io
'easy_thumbnails',
'filer',
'mptt',
'filer', # https://django-filer.readthedocs.io
#! 'mptt',
]
# http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html#using-celery-with-django
'django_celery_results', # http://django-celery-results.readthedocs.io/en/latest/
'django_celery_beat', # http://django-celery-beat.readthedocs.io/en/latest/
INSTALLED_APPS += [
'ClimbingAssoPortal.apps.ClimbingAssoPortalConfig',
]
'health_check', # http://django-health-check.readthedocs.io/en/latest/index.html
'health_check.db', # stock Django health checkers
'health_check.cache',
'health_check.storage',
# 'health_check.contrib.celery', # requires celery
'health_check.contrib.psutil', # disk and memory utilization; requires psutil
# https://github.com/applecat/django-simple-poll
# https://github.com/byteweaver/django-polls
# https://github.com/hmtanbir/django-easy-poll
'graphene_django', # http://docs.graphene-python.org/projects/django/en/latest
####################################################################################################
'ClimbingAssoPortal.apps.ClimbingAssoPortalConfig',
MIDDLEWARE_CLASSES = []
# https://github.com/applecat/django-simple-poll
# https://github.com/byteweaver/django-polls
# https://github.com/hmtanbir/django-easy-poll
]
if USE_PROMETHEUS:
MIDDLEWARE_CLASSES.append('django_prometheus.middleware.PrometheusBeforeMiddleware')
MIDDLEWARE = [
#! 'django.middleware.cache.UpdateCacheMiddleware',
......@@ -137,6 +160,9 @@ MIDDLEWARE = [
#! 'django.middleware.cache.FetchFromCacheMiddleware',
]
if USE_PROMETHEUS:
MIDDLEWARE_CLASSES.append('django_prometheus.middleware.PrometheusAfterMiddleware')
####################################################################################################
#
# Template
......
......@@ -146,6 +146,10 @@ AUTH_PASSWORD_VALIDATORS = [ # FOR DEV TEST ONLY !!!
POSTGRESQL_DESCRIPTION = 'Climbing Asso Portal Database'
POSTGRESQL_LOCAL = 'fr_FR.UTF8'
# Fixme: postgis ???
# if settings.USE_PROMETHEUS:
# engine = 'django_prometheus.db.backends.XXX'
DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
......@@ -208,6 +212,9 @@ CACHES = {
}
}
# if USE_PROMETHEUS:
# memcached_backend = 'django_prometheus.cache.backends.memcached',
# CACHES = {
# 'default': {
# 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
......
......@@ -55,12 +55,16 @@ urlpatterns = [
# Admin install this autocomplete feature where term are searched in search_fields
# /admin/APPLICATION/MODEL/autocomplete/?term=XYZ
path('health_status/{}/'.format(settings.HEALTH_CHECK_URL_KEY), include('health_check.urls')),
path('filer/', include('filer.urls')),
path('account/', include('account.urls')),
path('filer/', include('filer.urls')),
path('health_status/{}/'.format(settings.HEALTH_CHECK_URL_KEY), include('health_check.urls')),
path('select2/', include('django_select2.urls')),
]
if settings.USE_PROMETHEUS:
urlpatterns.append(path('', include('django_prometheus.urls')))
urlpatterns += [
path('', include('ClimbingAssoPortal.urls')),
]
......
......@@ -20,6 +20,8 @@
"""Module to implement duration in second.
See also :mode:`datetime.timedelta`
Example of usage::
dt = 10@u_s
......@@ -40,63 +42,87 @@ Example of usage::
__all__ = [
'Duration',
'u_s',
'u_min',
'u_hour',
'u_day',
]
####################################################################################################
class Duration:
class IntUnit:
##############################################
def __init__(self, value):
self._value = value
##############################################
def __int__(self):
return int(self._value)
##############################################
def __float__(self):
def __str__(self):
return str(self._value)
return float(self._value)
##############################################
def __mul__(self, other):
return self.__class__(int(self) * int(other))
##############################################
def __str__(self):
def __rmatmul__(self, other):
return self.__mul__(other)
return str(self._value)
##############################################
def __imul__(self, other):
self._value *= int(other)
return self
##############################################
def __mul__(self, other):
def __rmul__(self, other):
return self.__mul__(other)
##############################################
return Duration(self._value * float(other))
def __truediv__(self, other):
return int(self) / int(other)
####################################################################################################
class FloatUnit(IntUnit):
##############################################
def __mul__(self, other):
def __float__(self):
return float(self._value)
return Duration(float(self) * float(other))
##############################################
def __mul__(self, other):
return self.__class__(float(self) * float(other))
##############################################
def __rmul__(self, other):
return self.__mul__(other)
def __imul__(self, other):
self._value *= float(other)
return self
##############################################
def __rmatmul__(self, other):
return self.__mul__(other)
def __truediv__(self, other):
return float(self) / float(other)
####################################################################################################
class Duration(FloatUnit):
pass
u_s = Duration(1)
u_min = Duration(60)
u_min = u_s * 60
u_hour = u_min * 60
u_day = u_hour * 24
####################################################################################################
#
# Climbing Asso Portal - A Portal for Climbing Club (Association)
# Copyright (C) 2018 Fabrice Salvaire
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
####################################################################################################
####################################################################################################
#
# cf. https://docs.python.org/3.6/library/wsgiref.html
# https://www.python.org/dev/peps/pep-3333
#
# Test using
#
# server side
# python fake-wsgi-server.py &
# or
# /.../gunicorn --bind 127.0.0.1:8000 fake-wsgi-server:demo_app
#
# client side
# http localhost:8000
#
####################################################################################################
####################################################################################################
#
# HTTP/1.0 200 OK
# Content-type: text/plain; charset=utf-8
# Date: Wed, 11 Apr 2018 17:09:05 GMT
# Server: WSGIServer/0.2 CPython/3.6.5
#
# ...
# _: /home/opt/python-virtual-env/py36/bin/python
# SERVER_NAME: isis.localdomain
# GATEWAY_INTERFACE: CGI/1.1
# SERVER_PORT: 8000
# REMOTE_HOST:
# CONTENT_LENGTH:
# SCRIPT_NAME:
# SERVER_PROTOCOL: HTTP/1.1
# SERVER_SOFTWARE: WSGIServer/0.2
# REQUEST_METHOD: GET
# PATH_INFO: /
# QUERY_STRING:
# REMOTE_ADDR: 127.0.0.1
# CONTENT_TYPE: text/plain
# HTTP_HOST: localhost:8000
# HTTP_USER_AGENT: HTTPie/0.9.4
# HTTP_ACCEPT_ENCODING: gzip, deflate
# HTTP_ACCEPT: */*
# HTTP_CONNECTION: keep-alive
# wsgi.input: <_io.BufferedReader name=4>
# wsgi.errors: <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>
# wsgi.version: (1, 0)
# wsgi.run_once: False
# wsgi.url_scheme: http
# wsgi.multithread: True
# wsgi.multiprocess: False
# wsgi.file_wrapper: <class 'wsgiref.util.FileWrapper'>
#
####################################################################################################
####################################################################################################
from wsgiref.simple_server import make_server, demo_app
from wsgiref.util import setup_testing_defaults
####################################################################################################
def hello_application(environ, start_response):
# environ is a dictionary containing CGI environment variables as well as other request
# parameters and metadata under well-defined keys.
# start_response is a callable taking two positional parameters, status and response_headers.
start_response('200 OK', [('Content-Type', 'text/plain')])
# Makes the callable into a generator.
# The body of the response is returned as an iterable of byte strings.
yield b'Hello, World\n'
####################################################################################################
def environ_application(environ, start_response):
# Update environ with trivial defaults for testing purposes.
setup_testing_defaults(environ)
status = '200 OK'
headers = [('Content-type', 'text/plain; charset=utf-8')]
start_response(status, headers)
ret = [('{}: {}\n'.format(key, value)).encode('utf-8')
for key, value in environ.items()]
return ret
####################################################################################################
if __name__ == '__main__':
host = ''
port = 8000
app = demo_app
# app = environ_application
# app = hello_application
with make_server(host, port, app) as httpd:
print('Listening on port {} ...'.format(port))
httpd.serve_forever()
/*
Graphite Required Variable:
(Leave this unset to avoid sending stats to Graphite.
Set debug flag and leave this unset to run in 'dry' debug mode -
useful for testing statsd clients without a Graphite server.)
graphiteHost: hostname or IP of Graphite server
Optional Variables:
graphitePort: port for the graphite text collector [default: 2003]
graphitePicklePort: port for the graphite pickle collector [default: 2004]
graphiteProtocol: either 'text' or 'pickle' [default: 'text']
backends: an array of backends to load. Each backend must exist
by name in the directory backends/. If not specified,
the default graphite backend will be loaded.
* example for console and graphite:
[ "./backends/console", "./backends/graphite" ]
servers: an array of server configurations.
If not specified, the server, address,
address_ipv6, and port top-level configuration
options are used to configure a single server for
backwards-compatibility
Each server configuration supports the following keys:
server: the server to load. The server must exist by name in the directory
servers/. If not specified, the default udp server will be loaded.
* example for tcp server:
"./servers/tcp"
address: address to listen on [default: 0.0.0.0]
address_ipv6: defines if the address is an IPv4 or IPv6 address [true or false, default: false]
port: port to listen for messages on [default: 8125]
socket: (only for tcp servers) path to unix domain socket which will be used to receive
metrics [default: undefinded]
socket_mod: (only for tcp servers) file mode which should be applied to unix domain socket, relevant
only if socket option is used [default: undefined]
debug: debug flag [default: false]
mgmt_address: address to run the management TCP interface on
[default: 0.0.0.0]
mgmt_port: port to run the management TCP interface on [default: 8126]
title: Allows for overriding the process title. [default: statsd]
if set to false, will not override the process title and let the OS set it.
The length of the title has to be less than or equal to the binary name + cli arguments
NOTE: This does not work on Mac's with node versions prior to v0.10
healthStatus: default health status to be returned and statsd process starts ['up' or 'down', default: 'up']
dumpMessages: log all incoming messages
flushInterval: interval (in ms) to flush metrics to each backend
percentThreshold: for time information, calculate the Nth percentile(s)
(can be a single value or list of floating-point values)
negative values mean to use "top" Nth percentile(s) values
[%, default: 90]
flush_counts: send stats_counts metrics [default: true]
keyFlush: log the most frequently sent keys [object, default: undefined]
interval: how often to log frequent keys [ms, default: 0]
percent: percentage of frequent keys to log [%, default: 100]
log: location of log file for frequent keys [default: STDOUT]
deleteIdleStats: don't send values to graphite for inactive counters, sets, gauges, or timers
as opposed to sending 0. For gauges, this unsets the gauge (instead of sending
the previous value). Can be individually overriden. [default: false]
deleteGauges: don't send values to graphite for inactive gauges, as opposed to sending the previous value [default: false]
deleteTimers: don't send values to graphite for inactive timers, as opposed to sending 0 [default: false]
deleteSets: don't send values to graphite for inactive sets, as opposed to sending 0 [default: false]
deleteCounters: don't send values to graphite for inactive counters, as opposed to sending 0 [default: false]
prefixStats: prefix to use for the statsd statistics data for this running instance of statsd [default: statsd]
applies to both legacy and new namespacing
keyNameSanitize: sanitize all stat names on ingress [default: true]
If disabled, it is up to the backends to sanitize keynames
as appropriate per their storage requirements.
console:
prettyprint: whether to prettyprint the console backend
output [true or false, default: true]
log: log settings [object, default: undefined]
backend: where to log: stdout or syslog [string, default: stdout]
application: name of the application for syslog [string, default: statsd]
level: log level for [node-]syslog [string, default: LOG_INFO]
graphite:
legacyNamespace: use the legacy namespace [default: true]
globalPrefix: global prefix to use for sending stats to graphite [default: "stats"]
prefixCounter: graphite prefix for counter metrics [default: "counters"]
prefixTimer: graphite prefix for timer metrics [default: "timers"]
prefixGauge: graphite prefix for gauge metrics [default: "gauges"]
prefixSet: graphite prefix for set metrics [default: "sets"]
globalSuffix: global suffix to use for sending stats to graphite [default: ""]
This is particularly useful for sending per host stats by
settings this value to: require('os').hostname().split('.')[0]
repeater: an array of hashes of the for host: and port:
that details other statsd servers to which the received
packets should be "repeated" (duplicated to).
e.g. [ { host: '10.10.10.10', port: 8125 },
{ host: 'observer', port: 88125 } ]
repeaterProtocol: whether to use udp4, udp6, or tcp for repeaters.
["udp4," "udp6", or "tcp" default: "udp4"]
histogram: for timers, an array of mappings of strings (to match metrics) and
corresponding ordered non-inclusive upper limits of bins.
For all matching metrics, histograms are maintained over
time by writing the frequencies for all bins.
'inf' means infinity. A lower limit of 0 is assumed.
default: [], meaning no histograms for any timer.
First match wins. examples:
* histogram to only track render durations, with unequal
class intervals and catchall for outliers:
[ { metric: 'render', bins: [ 0.01, 0.1, 1, 10, 'inf'] } ]
* histogram for all timers except 'foo' related,
equal class interval and catchall for outliers:
[ { metric: 'foo', bins: [] },
{ metric: '', bins: [ 50, 100, 150, 200, 'inf'] } ]
automaticConfigReload: whether to watch the config file and reload it when it
changes. The default is true. Set this to false to disable.
*/
{
graphiteHost: 'localhost',
port: 8125,
graphitePort: 2003,
backends: [
'./backends/graphite',
'./backends/console',
],
}
# Markdown==2.6.11
# Pillow==5.0.0
Django==2.0.3
IntervalArithmetic
IntervalArithmetic=0.2.0
Jinja2==2.10
celery==4.1.0
coreapi==2.3.3
......@@ -21,4 +21,5 @@ djangorestframework-gis==0.12
djangorestframework==3.7.7
drf-yasg[validation]==1.6.0
easy-thumbnails==2.5
prometheus_client=0.2.0
requests==2.18.4
......@@ -2,4 +2,4 @@
Sphinx==1.7.1
django_babel==0.6.2
ansicolors==1.1.8
googletrans
googletrans==2.2.0
ClimbingAssoPortal/static-src/
\ No newline at end of file