From 3dd2ccf56ecfb791e9f9b63e909c0930de369af6 Mon Sep 17 00:00:00 2001 From: Mohamed Nouffer Date: Mon, 14 Mar 2022 10:50:11 +0530 Subject: [PATCH] update --- .gitignore | 334 ++++++++--------- Dockerfile.gdal | 110 +++--- Makefile | 66 ++-- config/asgi.py | 32 +- config/settings.py | 334 ++++++++--------- config/urls.py | 56 +-- config/wsgi.py | 32 +- docker-compose.yaml | 82 ++--- dockerignore | 108 +++--- manage.py | 44 +-- requirements.txt | 130 +++---- rog/admin.py | 58 +-- rog/apps.py | 12 +- rog/choices.py | 12 +- rog/mapping.py | 72 ++-- rog/models.py | 850 ++++++++++++++++++++++---------------------- rog/serializers.py | 82 +++-- rog/tests.py | 6 +- rog/urls.py | 32 +- rog/views.py | 76 ++-- 20 files changed, 1283 insertions(+), 1245 deletions(-) diff --git a/.gitignore b/.gitignore index a012b54..8770f08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,167 +1,167 @@ - -# Created by https://www.toptal.com/developers/gitignore/api/django -# Edit at https://www.toptal.com/developers/gitignore?templates=django - -### Django ### -*.log -*.pot -*.pyc -__pycache__/ -local_settings.py -db.sqlite3 -db.sqlite3-journal -media - -# If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/ -# in your Git repository. Update and uncomment the following line accordingly. -# /staticfiles/ - -### Django.Python Stack ### -# Byte-compiled / optimized / DLL files -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -cover/ - -# Translations -*.mo - -# Django stuff: - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -.pybuilder/ -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# pytype static type analyzer -.pytype/ - -# Cython debug symbols -cython_debug/ - -# PyCharm -# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ - -# End of https://www.toptal.com/developers/gitignore/api/django + +# Created by https://www.toptal.com/developers/gitignore/api/django +# Edit at https://www.toptal.com/developers/gitignore?templates=django + +### Django ### +*.log +*.pot +*.pyc +__pycache__/ +local_settings.py +db.sqlite3 +db.sqlite3-journal +media + +# If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/ +# in your Git repository. Update and uncomment the following line accordingly. +# /staticfiles/ + +### Django.Python Stack ### +# Byte-compiled / optimized / DLL files +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo + +# Django stuff: + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# End of https://www.toptal.com/developers/gitignore/api/django diff --git a/Dockerfile.gdal b/Dockerfile.gdal index b4e236e..0b214f3 100644 --- a/Dockerfile.gdal +++ b/Dockerfile.gdal @@ -1,55 +1,55 @@ -# FROM python:3.9.9-slim-buster -FROM osgeo/gdal:ubuntu-small-3.4.0 - -WORKDIR /app - -LABEL maintainer="nouffer@gmail.com" -LABEL description="Development image for the Rogaining JP" - -ENV PYTHONDONTWRITEBYTECODE 1 - -ENV PYTHONUNBUFFERED 1 - -ARG TZ Asia/Tokyo \ - DEBIAN_FRONTEND=noninteractive - - -RUN apt-get update -y - -# Install GDAL dependencies -RUN apt-get install -y libgdal-dev g++ --no-install-recommends && \ - apt-get clean -y - - - -# Update C env vars so compiler can find gdal -ENV CPLUS_INCLUDE_PATH=/usr/include/gdal -ENV C_INCLUDE_PATH=/usr/include/gdal - - -RUN apt-get update \ - && apt-get -y install netcat gcc postgresql \ - && apt-get clean - -RUN apt-get update \ - && apt-get install -y binutils libproj-dev gdal-bin python3-gdal - -RUN apt-get install -y libcurl4-openssl-dev libssl-dev - -RUN apt-get install -y libspatialindex-dev - -RUN apt-get install -y python3 - -RUN apt-get update && apt-get install -y \ - python3-pip - -RUN pip install --upgrade pip - -RUN apt-get update - -COPY ./requirements.txt /app/requirements.txt - -RUN pip install -r requirements.txt - -COPY . /app - +# FROM python:3.9.9-slim-buster +FROM osgeo/gdal:ubuntu-small-3.4.0 + +WORKDIR /app + +LABEL maintainer="nouffer@gmail.com" +LABEL description="Development image for the Rogaining JP" + +ENV PYTHONDONTWRITEBYTECODE 1 + +ENV PYTHONUNBUFFERED 1 + +ARG TZ Asia/Tokyo \ + DEBIAN_FRONTEND=noninteractive + + +RUN apt-get update -y + +# Install GDAL dependencies +RUN apt-get install -y libgdal-dev g++ --no-install-recommends && \ + apt-get clean -y + + + +# Update C env vars so compiler can find gdal +ENV CPLUS_INCLUDE_PATH=/usr/include/gdal +ENV C_INCLUDE_PATH=/usr/include/gdal + + +RUN apt-get update \ + && apt-get -y install netcat gcc postgresql \ + && apt-get clean + +RUN apt-get update \ + && apt-get install -y binutils libproj-dev gdal-bin python3-gdal + +RUN apt-get install -y libcurl4-openssl-dev libssl-dev + +RUN apt-get install -y libspatialindex-dev + +RUN apt-get install -y python3 + +RUN apt-get update && apt-get install -y \ + python3-pip + +RUN pip install --upgrade pip + +RUN apt-get update + +COPY ./requirements.txt /app/requirements.txt + +RUN pip install -r requirements.txt + +COPY . /app + diff --git a/Makefile b/Makefile index 570ffee..b68225c 100644 --- a/Makefile +++ b/Makefile @@ -1,33 +1,33 @@ - - -ifneq (,$(wildcard ./.env)) - include .env - export - ENV_FILE_PARAM = --env-file .env -endif - -build: - docker-compose up --build -d --remove-orphans -up: - docker-compose up -d -down: - docker-compose down -logs: - docker-compose logs -migrate: - docker-compose exec api python3 manage.py migrate --noinput -makemigrations: - docker-compose exec api python3 manage.py makemigrations - -superuser: - docker-compose exec api python3 manage.py createsuperuser - -down-v: - docker-compose down -v - -volume: - docker volume inspect rog_src_postgres_data - -shell: - docker-compose exec api python3 manage.py shell - + + +ifneq (,$(wildcard ./.env)) + include .env + export + ENV_FILE_PARAM = --env-file .env +endif + +build: + docker-compose up --build -d --remove-orphans +up: + docker-compose up -d +down: + docker-compose down +logs: + docker-compose logs +migrate: + docker-compose exec api python3 manage.py migrate --noinput +makemigrations: + docker-compose exec api python3 manage.py makemigrations + +superuser: + docker-compose exec api python3 manage.py createsuperuser + +down-v: + docker-compose down -v + +volume: + docker volume inspect rog_src_postgres_data + +shell: + docker-compose exec api python3 manage.py shell + diff --git a/config/asgi.py b/config/asgi.py index 8dad602..fd09b89 100644 --- a/config/asgi.py +++ b/config/asgi.py @@ -1,16 +1,16 @@ -""" -ASGI config for config project. - -It exposes the ASGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/ -""" - -import os - -from django.core.asgi import get_asgi_application - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') - -application = get_asgi_application() +""" +ASGI config for config project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') + +application = get_asgi_application() diff --git a/config/settings.py b/config/settings.py index bd67a04..5464be9 100644 --- a/config/settings.py +++ b/config/settings.py @@ -1,167 +1,167 @@ -""" -Django settings for config project. - -Generated by 'django-admin startproject' using Django 3.2.9. - -For more information on this file, see -https://docs.djangoproject.com/en/3.2/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/3.2/ref/settings/ -""" - -from pathlib import Path -import environ -import os - -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent - -env = environ.Env(DEBUG=(bool, False)) -environ.Env.read_env(env_file=".env") - - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ - -# SECURITY WARNING: keep the secret key used in production secret! -#SECRET_KEY = 'django-insecure-@!z!i#bheb)(o1-e2tss(i^dav-ql=cm4*+$unm^3=4)k_ttda' -SECRET_KEY = env("SECRET_KEY") - -# SECURITY WARNING: don't run with debug turned on in production! -#DEBUG = True -DEBUG = env("DEBUG") - -#ALLOWED_HOSTS = [] -ALLOWED_HOSTS = env("ALLOWED_HOSTS").split(" ") - - -# Application definition - -INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'django.contrib.gis', - 'rest_framework', - 'rest_framework_gis', - 'leaflet', - 'leaflet_admin_list', - 'rog.apps.RogConfig', -] - -MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', -] - -ROOT_URLCONF = 'config.urls' - -TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [BASE_DIR / 'templates'], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - ], - }, - }, -] - -WSGI_APPLICATION = 'config.wsgi.application' - - -# Database -# https://docs.djangoproject.com/en/3.2/ref/settings/#databases - -DATABASES = { - 'default': { - 'ENGINE': 'django.contrib.gis.db.backends.postgis', - 'NAME': env("POSTGRES_DBNAME"), - 'USER': env("POSTGRES_USER"), - 'PASSWORD': env("POSTGRES_PASS"), - 'HOST': env("PG_HOST"), - 'PORT': env("PG_PORT") - } -} - - -# Password validation -# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators - -AUTH_PASSWORD_VALIDATORS = [ - { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', - }, -] - - -# Internationalization -# https://docs.djangoproject.com/en/3.2/topics/i18n/ - -LANGUAGE_CODE = 'en-us' - -TIME_ZONE = 'Asia/Tokyo' - -USE_I18N = True - -USE_L10N = True - -USE_TZ = True - - -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/3.2/howto/static-files/ - -STATIC_URL = '/static/' - -#STATIC_URL = '/static2/' -STATIC_ROOT = BASE_DIR / "static" - -MEDIA_URL = '/media/' -MEDIA_ROOT = BASE_DIR / "media/" - -#STATICFILES_DIRS = (os.path.join(BASE_DIR, "static2"),os.path.join(BASE_DIR, "media")) - - - -# Default primary key field type -# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field - -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' - -DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' - -LEAFLET_CONFIG = { - 'DEFAULT_CENTER': (35.41864442627996, 138.14094040951784), - 'DEFAULT_ZOOM': 6, - 'MIN_ZOOM': 3, - 'MAX_ZOOM': 19, - 'DEFAULT_PRECISION': 6, - 'SCALE':"both", - 'ATTRIBUTION_PREFIX':"ROGAINING API", - 'TILES': [('Satellite', 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {'attribution': '© ESRI', 'maxZoom': 19}), - ('Streets', 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {'attribution': '© Contributors'})] -} +""" +Django settings for config project. + +Generated by 'django-admin startproject' using Django 3.2.9. + +For more information on this file, see +https://docs.djangoproject.com/en/3.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/3.2/ref/settings/ +""" + +from pathlib import Path +import environ +import os + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + +env = environ.Env(DEBUG=(bool, False)) +environ.Env.read_env(env_file=".env") + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +#SECRET_KEY = 'django-insecure-@!z!i#bheb)(o1-e2tss(i^dav-ql=cm4*+$unm^3=4)k_ttda' +SECRET_KEY = env("SECRET_KEY") + +# SECURITY WARNING: don't run with debug turned on in production! +#DEBUG = True +DEBUG = env("DEBUG") + +#ALLOWED_HOSTS = [] +ALLOWED_HOSTS = env("ALLOWED_HOSTS").split(" ") + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'django.contrib.gis', + 'rest_framework', + 'rest_framework_gis', + 'leaflet', + 'leaflet_admin_list', + 'rog.apps.RogConfig', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'config.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [BASE_DIR / 'templates'], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'config.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/3.2/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.contrib.gis.db.backends.postgis', + 'NAME': env("POSTGRES_DBNAME"), + 'USER': env("POSTGRES_USER"), + 'PASSWORD': env("POSTGRES_PASS"), + 'HOST': env("PG_HOST"), + 'PORT': env("PG_PORT") + } +} + + +# Password validation +# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/3.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'Asia/Tokyo' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/3.2/howto/static-files/ + +STATIC_URL = '/static/' + +#STATIC_URL = '/static2/' +STATIC_ROOT = BASE_DIR / "static" + +MEDIA_URL = '/media/' +MEDIA_ROOT = BASE_DIR / "media/" + +#STATICFILES_DIRS = (os.path.join(BASE_DIR, "static2"),os.path.join(BASE_DIR, "media")) + + + +# Default primary key field type +# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + +LEAFLET_CONFIG = { + 'DEFAULT_CENTER': (35.41864442627996, 138.14094040951784), + 'DEFAULT_ZOOM': 6, + 'MIN_ZOOM': 3, + 'MAX_ZOOM': 19, + 'DEFAULT_PRECISION': 6, + 'SCALE':"both", + 'ATTRIBUTION_PREFIX':"ROGAINING API", + 'TILES': [('Satellite', 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {'attribution': '© ESRI', 'maxZoom': 19}), + ('Streets', 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {'attribution': '© Contributors'})] +} diff --git a/config/urls.py b/config/urls.py index 33576f7..6d58b26 100644 --- a/config/urls.py +++ b/config/urls.py @@ -1,28 +1,28 @@ -"""config URL Configuration - -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/3.2/topics/http/urls/ -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: path('', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.urls import include, path - 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) -""" -from django.contrib import admin -from django.urls import path, include -from django.conf import settings -from django.conf.urls.static import static - -urlpatterns = [ - path('admin/', admin.site.urls), - path('api/', include("rog.urls")), -]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) - -admin.site.site_header = "ROGANING" -admin.site.site_title = "Roganing Admin Portal" -admin.site.index_title = "Welcome to Roganing Portal" +"""config URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/3.2/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path, include +from django.conf import settings +from django.conf.urls.static import static + +urlpatterns = [ + path('admin/', admin.site.urls), + path('api/', include("rog.urls")), +]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + +admin.site.site_header = "ROGANING" +admin.site.site_title = "Roganing Admin Portal" +admin.site.index_title = "Welcome to Roganing Portal" diff --git a/config/wsgi.py b/config/wsgi.py index 8915671..0ba5f21 100644 --- a/config/wsgi.py +++ b/config/wsgi.py @@ -1,16 +1,16 @@ -""" -WSGI config for config project. - -It exposes the WSGI callable as a module-level variable named ``application``. - -For more information on this file, see -https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/ -""" - -import os - -from django.core.wsgi import get_wsgi_application - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') - -application = get_wsgi_application() +""" +WSGI config for config project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') + +application = get_wsgi_application() diff --git a/docker-compose.yaml b/docker-compose.yaml index 7dffd97..b33064f 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,42 +1,42 @@ -version: "3.9" - -services: - api: - build: - context: . - dockerfile: Dockerfile.gdal - command: python3 manage.py runserver 0.0.0.0:8100 - volumes: - - .:/app - ports: - - 8100:8100 - env_file: - - .env - restart: "on-failure" - depends_on: - - postgres-db - networks: - - rog-api - - postgres-db: - image: kartoza/postgis:12.0 - ports: - - 5432:5432 - volumes: - - postgres_data:/var/lib/postgresql - environment: - - POSTGRES_USER=${POSTGRES_USER} - - POSTGRES_PASS=${POSTGRES_PASS} - - POSTGRES_DBNAME=${POSTGRES_DBNAME} - restart: "on-failure" - networks: - - rog-api - - -networks: - rog-api: - driver: bridge - -volumes: - postgres_data: +version: "3.9" + +services: + api: + build: + context: . + dockerfile: Dockerfile.gdal + command: python3 manage.py runserver 0.0.0.0:8100 + volumes: + - .:/app + ports: + - 8100:8100 + env_file: + - .env + restart: "on-failure" + depends_on: + - postgres-db + networks: + - rog-api + + postgres-db: + image: kartoza/postgis:12.0 + ports: + - 5432:5432 + volumes: + - postgres_data:/var/lib/postgresql + environment: + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASS=${POSTGRES_PASS} + - POSTGRES_DBNAME=${POSTGRES_DBNAME} + restart: "on-failure" + networks: + - rog-api + + +networks: + rog-api: + driver: bridge + +volumes: + postgres_data: geoserver-data: \ No newline at end of file diff --git a/dockerignore b/dockerignore index 7aa35c9..130e99f 100644 --- a/dockerignore +++ b/dockerignore @@ -1,55 +1,55 @@ -# Docker/Podman image doesn't need any files that git doesn't track. -#Therefore the .dockerignore largely follows the structure of .gitignore. -# C extensions -*.so -# Packages -*.egg* -*.egg-info -dist -build -eggs -parts -bin -var -sdist -develop-eggs -.installed.cfg -lib -lib64 -# Installer logs -pip-log.txt -# Unit test / coverage reports -cover/ -.coverage* -!.coveragerc -.tox -nosetests.xml -.testrepository -.venv -.stestr/* -# Translations -*.mo -# Mr Developer -.mr.developer.cfg -.project -.pydevproject -# Complexity -output/*.html -output/*/index.html -# Sphinx -doc/build -doc/source/reference/api/ -# pbr generates these -AUTHORS -ChangeLog -# Editors -*~ -.*.swp -.*sw? -# Files created by releasenotes build -releasenotes/build -# Ansible specific -hosts -*.retry -#Vagrantfiles, since we are using docker +# Docker/Podman image doesn't need any files that git doesn't track. +#Therefore the .dockerignore largely follows the structure of .gitignore. +# C extensions +*.so +# Packages +*.egg* +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg +lib +lib64 +# Installer logs +pip-log.txt +# Unit test / coverage reports +cover/ +.coverage* +!.coveragerc +.tox +nosetests.xml +.testrepository +.venv +.stestr/* +# Translations +*.mo +# Mr Developer +.mr.developer.cfg +.project +.pydevproject +# Complexity +output/*.html +output/*/index.html +# Sphinx +doc/build +doc/source/reference/api/ +# pbr generates these +AUTHORS +ChangeLog +# Editors +*~ +.*.swp +.*sw? +# Files created by releasenotes build +releasenotes/build +# Ansible specific +hosts +*.retry +#Vagrantfiles, since we are using docker Vagrantfile.* \ No newline at end of file diff --git a/manage.py b/manage.py index 8e7ac79..192aaab 100755 --- a/manage.py +++ b/manage.py @@ -1,22 +1,22 @@ -#!/usr/bin/env python -"""Django's command-line utility for administrative tasks.""" -import os -import sys - - -def main(): - """Run administrative tasks.""" - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') - try: - from django.core.management import execute_from_command_line - except ImportError as exc: - raise ImportError( - "Couldn't import Django. Are you sure it's installed and " - "available on your PYTHONPATH environment variable? Did you " - "forget to activate a virtual environment?" - ) from exc - execute_from_command_line(sys.argv) - - -if __name__ == '__main__': - main() +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/requirements.txt b/requirements.txt index 6be9c95..e797509 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,65 +1,65 @@ -affine==2.3.0 -asgiref==3.4.1 -attrs==21.2.0 -black==21.11b0 -certifi==2021.10.8 -charset-normalizer==2.0.8 -click==8.0.3 -click-plugins==1.1.1 -cligj==0.7.2 -cycler==0.11.0 -Django==3.2.9 -django-adminlte-3==0.1.6 -django-environ==0.8.1 -django-filter==21.1 -django-leaflet==0.28.2 -django-leaflet-admin-list==0.0.4 -django-suit==2.0a1 -djangorestframework==3.12.4 -djangorestframework-gis==0.17 -Fiona==1.8.20 -flake8==4.0.1 -fonttools==4.28.2 -# GDAL==3.3.0 -GeoAlchemy2==0.9.4 -geopandas==0.10.2 -geoserver-rest==2.1.4 -greenlet==1.1.2 -idna==3.3 -kiwisolver==1.3.2 -matplotlib==3.5.0 -mccabe==0.6.1 -munch==2.5.0 -mypy-extensions==0.4.3 -numpy==1.21.4 -packaging==21.3 -pandas==1.3.4 -pathspec==0.9.0 -Pillow==8.4.0 -platformdirs==2.4.0 -psycopg2-binary==2.9.2 -pycodestyle==2.8.0 -pycurl==7.44.1 -pyflakes==2.4.0 -Pygments==2.10.0 -pyparsing==3.0.6 -pyproj==3.3.0 -python-dateutil==2.8.2 -pytz==2021.3 -rasterio==1.2.10 -regex==2021.11.10 -requests==2.26.0 -Rtree==0.9.7 -scipy==1.7.3 -seaborn==0.11.2 -setuptools-scm==6.3.2 -Shapely==1.8.0 -six==1.16.0 -snuggs==1.4.7 -SQLAlchemy==1.4.27 -sqlparse==0.4.2 -tomli==1.2.2 -typing_extensions==4.0.0 -urllib3==1.26.7 -django-extra-fields==3.0.2 -django-phonenumber-field==6.1.0 +affine==2.3.0 +asgiref==3.4.1 +attrs==21.2.0 +black==21.11b0 +certifi==2021.10.8 +charset-normalizer==2.0.8 +click==8.0.3 +click-plugins==1.1.1 +cligj==0.7.2 +cycler==0.11.0 +Django==3.2.9 +django-adminlte-3==0.1.6 +django-environ==0.8.1 +django-filter==21.1 +django-leaflet==0.28.2 +django-leaflet-admin-list==0.0.4 +django-suit==2.0a1 +djangorestframework==3.12.4 +djangorestframework-gis==0.17 +Fiona==1.8.20 +flake8==4.0.1 +fonttools==4.28.2 +# GDAL==3.3.0 +GeoAlchemy2==0.9.4 +geopandas==0.10.2 +geoserver-rest==2.1.4 +greenlet==1.1.2 +idna==3.3 +kiwisolver==1.3.2 +matplotlib==3.5.0 +mccabe==0.6.1 +munch==2.5.0 +mypy-extensions==0.4.3 +numpy==1.21.4 +packaging==21.3 +pandas==1.3.4 +pathspec==0.9.0 +Pillow==8.4.0 +platformdirs==2.4.0 +psycopg2-binary==2.9.2 +pycodestyle==2.8.0 +pycurl==7.44.1 +pyflakes==2.4.0 +Pygments==2.10.0 +pyparsing==3.0.6 +pyproj==3.3.0 +python-dateutil==2.8.2 +pytz==2021.3 +rasterio==1.2.10 +regex==2021.11.10 +requests==2.26.0 +Rtree==0.9.7 +scipy==1.7.3 +seaborn==0.11.2 +setuptools-scm==6.3.2 +Shapely==1.8.0 +six==1.16.0 +snuggs==1.4.7 +SQLAlchemy==1.4.27 +sqlparse==0.4.2 +tomli==1.2.2 +typing_extensions==4.0.0 +urllib3==1.26.7 +django-extra-fields==3.0.2 +django-phonenumber-field==6.1.0 diff --git a/rog/admin.py b/rog/admin.py index a717577..349ee34 100644 --- a/rog/admin.py +++ b/rog/admin.py @@ -1,30 +1,30 @@ -from django.contrib import admin -from leaflet.admin import LeafletGeoAdmin -from leaflet.admin import LeafletGeoAdminMixin -from leaflet_admin_list.admin import LeafletAdminListMixin -from .models import RogUser, Location, SystemSettings, JoinedEvent, Favorite, TravelList, TravelPoint, ShapeLayers, Event, Location_line, Location_polygon - - -class RogAdmin(LeafletAdminListMixin, LeafletGeoAdminMixin, admin.ModelAdmin): - list_display=['title', 'venue', 'at_date',] - -class ShopAdmin(LeafletAdminListMixin, LeafletGeoAdminMixin, admin.ModelAdmin): - list_display=['name',] - -class EventRouteAdmin(LeafletAdminListMixin, LeafletGeoAdminMixin, admin.ModelAdmin): - list_display=['name',] - -class ShopRouteAdmin(LeafletAdminListMixin, LeafletGeoAdminMixin, admin.ModelAdmin): - list_display=['name',] - -admin.site.register(RogUser, admin.ModelAdmin) -admin.site.register(Location, LeafletGeoAdmin) -admin.site.register(SystemSettings, admin.ModelAdmin) -admin.site.register(JoinedEvent, admin.ModelAdmin) -admin.site.register(Favorite, admin.ModelAdmin) -admin.site.register(TravelList, admin.ModelAdmin) -admin.site.register(TravelPoint, admin.ModelAdmin) -admin.site.register(Event, admin.ModelAdmin) -admin.site.register(Location_line, LeafletGeoAdmin) -admin.site.register(Location_polygon, LeafletGeoAdmin) +from django.contrib import admin +from leaflet.admin import LeafletGeoAdmin +from leaflet.admin import LeafletGeoAdminMixin +from leaflet_admin_list.admin import LeafletAdminListMixin +from .models import RogUser, Location, SystemSettings, JoinedEvent, Favorite, TravelList, TravelPoint, ShapeLayers, Event, Location_line, Location_polygon + + +class RogAdmin(LeafletAdminListMixin, LeafletGeoAdminMixin, admin.ModelAdmin): + list_display=['title', 'venue', 'at_date',] + +class ShopAdmin(LeafletAdminListMixin, LeafletGeoAdminMixin, admin.ModelAdmin): + list_display=['name',] + +class EventRouteAdmin(LeafletAdminListMixin, LeafletGeoAdminMixin, admin.ModelAdmin): + list_display=['name',] + +class ShopRouteAdmin(LeafletAdminListMixin, LeafletGeoAdminMixin, admin.ModelAdmin): + list_display=['name',] + +admin.site.register(RogUser, admin.ModelAdmin) +admin.site.register(Location, LeafletGeoAdmin) +admin.site.register(SystemSettings, admin.ModelAdmin) +admin.site.register(JoinedEvent, admin.ModelAdmin) +admin.site.register(Favorite, admin.ModelAdmin) +admin.site.register(TravelList, admin.ModelAdmin) +admin.site.register(TravelPoint, admin.ModelAdmin) +admin.site.register(Event, admin.ModelAdmin) +admin.site.register(Location_line, LeafletGeoAdmin) +admin.site.register(Location_polygon, LeafletGeoAdmin) admin.site.register(ShapeLayers, admin.ModelAdmin) \ No newline at end of file diff --git a/rog/apps.py b/rog/apps.py index 85c3443..5e78452 100644 --- a/rog/apps.py +++ b/rog/apps.py @@ -1,6 +1,6 @@ -from django.apps import AppConfig - - -class RogConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'rog' +from django.apps import AppConfig + + +class RogConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'rog' diff --git a/rog/choices.py b/rog/choices.py index 04b7b66..175f7b7 100644 --- a/rog/choices.py +++ b/rog/choices.py @@ -1,7 +1,7 @@ -from django.utils.translation import gettext_lazy as _ - -LAYER_CHOICES = ( - (1, _("locations")), - (2, _("Location_line")), - (3, _("Location_polygon")), +from django.utils.translation import gettext_lazy as _ + +LAYER_CHOICES = ( + (1, _("locations")), + (2, _("Location_line")), + (3, _("Location_polygon")), ) \ No newline at end of file diff --git a/rog/mapping.py b/rog/mapping.py index a9981e9..911342b 100644 --- a/rog/mapping.py +++ b/rog/mapping.py @@ -1,37 +1,37 @@ -from django.contrib.gis.utils import LayerMapping - -location_mapping = { - 'location_id' : 'loc_id', - 'location_name' : 'loc_name', - 'category': 'category', - 'zip':'zip', - 'address':'address', - 'prefecture':'prefecture', - 'area':'area', - 'city':'city', - 'photos':'photos', - 'videos':'videos', - 'webcontents':'webcontent', - 'status':'status', - 'portal':'portal', - 'group':'group', - 'phone':'phone', - 'fax':'fax', - 'email':'email', - 'facility':'facility', - 'remark':'remark', - 'parammeters':'params', - 'tags':'tags', - 'geom': 'POINT', -} - -location_line_mapping = { - 'location_id' : 'loc_id', - 'geom': 'LINESTRING', -} - - -location_polygon_mapping = { - 'location_id' : 'loc_id', - 'geom': 'POLYGON', +from django.contrib.gis.utils import LayerMapping + +location_mapping = { + 'location_id' : 'loc_id', + 'location_name' : 'loc_name', + 'category': 'category', + 'zip':'zip', + 'address':'address', + 'prefecture':'prefecture', + 'area':'area', + 'city':'city', + 'photos':'photos', + 'videos':'videos', + 'webcontents':'webcontent', + 'status':'status', + 'portal':'portal', + 'group':'group', + 'phone':'phone', + 'fax':'fax', + 'email':'email', + 'facility':'facility', + 'remark':'remark', + 'parammeters':'params', + 'tags':'tags', + 'geom': 'POINT', +} + +location_line_mapping = { + 'location_id' : 'loc_id', + 'geom': 'LINESTRING', +} + + +location_polygon_mapping = { + 'location_id' : 'loc_id', + 'geom': 'POLYGON', } \ No newline at end of file diff --git a/rog/models.py b/rog/models.py index 490a86b..1eaf529 100644 --- a/rog/models.py +++ b/rog/models.py @@ -1,425 +1,425 @@ -from dataclasses import field -from pyexpat import model -from sre_constants import CH_LOCALE -from typing import ChainMap -from django.contrib.gis.db import models -from django.utils.translation import gettext_lazy as _ -from django.contrib.auth.models import User -from django.db.models.signals import post_save, post_delete, pre_save -from django.dispatch import receiver -import geopandas as gpd -from sqlalchemy import * -from geoalchemy2 import Geometry, WKTElement -import os, zipfile, glob -import environ -from geo.Postgres import Db -from sqlalchemy.sql.functions import mode -from .mapping import location_mapping, location_line_mapping, location_polygon_mapping -from .choices import LAYER_CHOICES -from django.contrib.gis.utils import LayerMapping -from django.apps import apps - -env = environ.Env(DEBUG=(bool, False)) -environ.Env.read_env(env_file=".env") - -db = Db(dbname=env("POSTGRES_DBNAME"), user=env("POSTGRES_USER"), password=env("POSTGRES_PASS"), host="postgres-db", port=env("PG_PORT")) - - -class RogUser(models.Model): - user=models.OneToOneField(User, on_delete=models.CASCADE) - email=models.EmailField(_('Email')) - phone=models.CharField(_('Phone Number'), max_length=55) - first_name=models.CharField(_('First Name'), max_length=255) - middle_name=models.CharField(_('Middle Name'), max_length=255, blank=True, null=True) - last_name=models.CharField(_('last_name'), max_length=255) - nickname=models.CharField(_('Nickname'), max_length=255, blank=True, null=True) - country=models.CharField(_('Country'), max_length=255, default='Japan') - language=models.CharField(_('Language'), max_length=255, default='Japanese') - prefecture=models.CharField(_('Prefecture'), max_length=255, blank=True, null=True) - sex=models.CharField(_('Sex'), max_length=255, default='unknown', blank=True, null=True) - birthyear=models.IntegerField(_('Birth year'), blank=True, null=True) - family_structure =models.IntegerField(_('Family Structure'), blank=True, null=True) - introducer = models.ForeignKey(User, related_name='introduced_uesr', on_delete=models.DO_NOTHING) - level= models.IntegerField(_('Level'), blank=True, null=True, default=0) - parammeters=models.CharField(_('Parameters'), max_length=512) - created_at=models.DateTimeField(auto_now_add=True) - last_updated_user=models.ForeignKey(User, related_name="roguser_updated_user", on_delete=models.DO_NOTHING) - last_updated_at=models.DateTimeField(auto_now=True) - - -class SystemSettings(models.Model): - setting_name=models.CharField(_('Settings Name'), max_length=255) - version=models.CharField(_('Version'), max_length=10, blank=True, null=True) - effective_date=models.DateTimeField() - end_date=models.DateTimeField() - parammeters=models.CharField(_('Parameters'), max_length=512) - created_at=models.DateTimeField(auto_now_add=True) - last_updated_user=models.ForeignKey(User, related_name="system_setting_updated_user", on_delete=models.DO_NOTHING) - last_updated_at=models.DateTimeField(auto_now=True) - -class Location(models.Model): - location_id=models.IntegerField(_('Location id'), blank=True, null=True) - location_name=models.CharField(_('Location Name'), max_length=255) - category=models.CharField(_('Category'), max_length=255, blank=True, null=True) - zip=models.CharField(_('Zip code'), max_length=12, blank=True, null=True) - address = models.CharField(_('Address'), max_length=512, blank=True, null=True) - prefecture = models.CharField(_('Prefecture'), max_length=255, blank=True, null=True) - area= models.CharField(_('Area'), max_length=255, blank=True, null=True) - city= models.CharField(_('City'), max_length=255, blank=True, null=True) - photos=models.CharField(_('Phptos'), max_length=255, blank=True, null=True) - videos=models.CharField(_('Videos'), max_length=255, blank=True, null=True) - webcontents=models.CharField(_('Web Content'), max_length=255, blank=True, null=True) - status=models.CharField(_('Status'),max_length=255, blank=True, null=True) - portal=models.CharField(_('Status'), max_length=255,blank=True, null=True) - group=models.CharField(_('Status'), max_length=255,blank=True, null=True) - phone=models.CharField(_('Status'), max_length=255,blank=True, null=True) - fax=models.CharField(_('Status'), max_length=255, blank=True, null=True) - email=models.EmailField(_('Email'), max_length=255,blank=True, null=True) - facility=models.CharField(_('Status'), max_length=255, blank=True, null=True) - remark=models.CharField(_('Status'), max_length=255, blank=True, null=True) - tags=models.CharField(_('Tags'), max_length=512, blank=True, null=True) - parammeters=models.CharField(_('Parameters'), max_length=512, blank=True, null=True) - created_at=models.DateTimeField(auto_now_add=True) - last_updated_user=models.ForeignKey(User, related_name="location_updated_user", on_delete=models.DO_NOTHING,blank=True, null=True) - last_updated_at=models.DateTimeField(auto_now=True) - geom=models.MultiPointField(srid=4326) - - def __str__(self): - return self.location_name - - -class Location_line(models.Model): - location_id=models.IntegerField(_('Location id'), blank=True, null=True) - location_name=models.CharField(_('Location Name'), max_length=255) - category=models.CharField(_('Category'), max_length=255, blank=True, null=True) - zip=models.CharField(_('Zip code'), max_length=12, blank=True, null=True) - address = models.CharField(_('Address'), max_length=512, blank=True, null=True) - prefecture = models.CharField(_('Prefecture'), max_length=255, blank=True, null=True) - area= models.CharField(_('Area'), max_length=255, blank=True, null=True) - city= models.CharField(_('City'), max_length=255, blank=True, null=True) - photos=models.CharField(_('Phptos'), max_length=255, blank=True, null=True) - videos=models.CharField(_('Videos'), max_length=255, blank=True, null=True) - webcontents=models.CharField(_('Web Content'), max_length=255, blank=True, null=True) - status=models.CharField(_('Status'),max_length=255, blank=True, null=True) - portal=models.CharField(_('Status'), max_length=255,blank=True, null=True) - group=models.CharField(_('Status'), max_length=255,blank=True, null=True) - phone=models.CharField(_('Status'), max_length=255,blank=True, null=True) - fax=models.CharField(_('Status'), max_length=255, blank=True, null=True) - email=models.EmailField(_('Email'), max_length=255,blank=True, null=True) - facility=models.CharField(_('Status'), max_length=255, blank=True, null=True) - remark=models.CharField(_('Status'), max_length=255, blank=True, null=True) - tags=models.CharField(_('Tags'), max_length=512, blank=True, null=True) - parammeters=models.CharField(_('Parameters'), max_length=512, blank=True, null=True) - created_at=models.DateTimeField(auto_now_add=True) - last_updated_user=models.ForeignKey(User, related_name="location_line_updated_user", on_delete=models.DO_NOTHING,blank=True, null=True) - last_updated_at=models.DateTimeField(auto_now=True) - geom=models.MultiLineStringField(srid=4326, blank=True, null=True) - - def __str__(self): - return str(self.location_id) - - - -class Location_polygon(models.Model): - location_id=models.IntegerField(_('Location id'), blank=True, null=True) - location_name=models.CharField(_('Location Name'), max_length=255) - category=models.CharField(_('Category'), max_length=255, blank=True, null=True) - zip=models.CharField(_('Zip code'), max_length=12, blank=True, null=True) - address = models.CharField(_('Address'), max_length=512, blank=True, null=True) - prefecture = models.CharField(_('Prefecture'), max_length=255, blank=True, null=True) - area= models.CharField(_('Area'), max_length=255, blank=True, null=True) - city= models.CharField(_('City'), max_length=255, blank=True, null=True) - photos=models.CharField(_('Phptos'), max_length=255, blank=True, null=True) - videos=models.CharField(_('Videos'), max_length=255, blank=True, null=True) - webcontents=models.CharField(_('Web Content'), max_length=255, blank=True, null=True) - status=models.CharField(_('Status'),max_length=255, blank=True, null=True) - portal=models.CharField(_('Status'), max_length=255,blank=True, null=True) - group=models.CharField(_('Status'), max_length=255,blank=True, null=True) - phone=models.CharField(_('Status'), max_length=255,blank=True, null=True) - fax=models.CharField(_('Status'), max_length=255, blank=True, null=True) - email=models.EmailField(_('Email'), max_length=255,blank=True, null=True) - facility=models.CharField(_('Status'), max_length=255, blank=True, null=True) - remark=models.CharField(_('Status'), max_length=255, blank=True, null=True) - tags=models.CharField(_('Tags'), max_length=512, blank=True, null=True) - parammeters=models.CharField(_('Parameters'), max_length=512, blank=True, null=True) - created_at=models.DateTimeField(auto_now_add=True) - last_updated_user=models.ForeignKey(User, related_name="location_polygon_updated_user", on_delete=models.DO_NOTHING,blank=True, null=True) - last_updated_at=models.DateTimeField(auto_now=True) - geom=models.MultiPolygonField(srid=4326, blank=True, null=True) - - def __str__(self): - return str(self.location_name) - - - -EVENT_STATUS = ( - ("PREPARING", _("Preparing")), - ("PROMOTION", _("Promotion")), - ("EVENT", _("Event")), - ("END", _("End")) -) - - - -class Event(models.Model): - tagname=models.CharField(_('Parameters'), max_length=512, blank=True, null=True) - status=models.CharField(max_length=256, choices=EVENT_STATUS) - price=models.IntegerField(_('Paid Amount'), default=0) - promotion_date=models.DateTimeField(_('Promotion date'), blank=True, null=True) - event_start=models.DateTimeField(_('Promotion date'), blank=True, null=True) - event_end=models.DateTimeField(_('Promotion date'), blank=True, null=True) - remark=models.CharField(max_length=256, blank=True, null=True) - parammeters=models.CharField(_('Parameters'), max_length=512, blank=True, null=True) - created_at=models.DateTimeField(auto_now_add=True) - last_updated_user=models.ForeignKey(User, related_name="event_updated_user", on_delete=models.DO_NOTHING,blank=True, null=True) - last_updated_at=models.DateTimeField(auto_now=True) - - -ROG_STATUS = ( - ("REGISTERED", _("Registered")), - ("ACCEPTED", _("accepted")), - ("PAID", _("paid")), - ("JOINED", _("joined")), - ("CANCELED", _("Canceled")) -) - -class JoinedEvent(models.Model): - user=models.ForeignKey(User, on_delete=models.DO_NOTHING) - tagname=models.CharField(_('Tag Name'), max_length=255, blank=True, null=True) - status=models.CharField(max_length=256, choices=ROG_STATUS) - registrationid=models.CharField(_('Registration Id'), max_length=56) - payment_code=models.CharField(_('Payment Code'), max_length=255) - paid=models.IntegerField(_('Paid Amount'), default=0) - remark=models.CharField(_('Remark'), max_length=255, blank=True, null=True) - parammeters=models.CharField(_('Parameters'), max_length=512) - created_at=models.DateTimeField(auto_now_add=True) - last_updated_user=models.ForeignKey(User, related_name="joined_event_updated_user", on_delete=models.DO_NOTHING) - last_updated_at=models.DateTimeField(auto_now=True) - - - -class Favorite(models.Model): - user=models.ForeignKey(User, on_delete=models.DO_NOTHING) - location=models.ForeignKey(Location, on_delete=models.CASCADE) - good=models.IntegerField(_('Good'), default=0) - favorite=models.IntegerField(_('Favorite'), default=0) - evaluation=models.IntegerField(_('Evaluation'), default=0) - number_visit=models.IntegerField(_('Good'), default=0) - last_visited=models.DateTimeField(_('Last Visited'), blank=True, null=True) - parammeters=models.CharField(_('Parameters'), max_length=512, blank=True, null=True) - created_at=models.DateTimeField(auto_now_add=True) - last_updated_user=models.ForeignKey(User, related_name="favorite_updated_user", on_delete=models.DO_NOTHING) - last_updated_at=models.DateTimeField(auto_now=True) - - - -TRAVEL_CATEGORY = ( - ("PRIVATE", _("Private")), - ("GROUP", _("Group")), - ("AGENT", _("Agent")), - ("ROGAINING", _("Rogaining")) -) - - - -class TravelList(models.Model): - travel_id= models.IntegerField(_('Travel Id')) - user=models.ForeignKey(User, on_delete=models.DO_NOTHING) - start_date=models.DateTimeField(_('Start date') ,blank=True, null=True) - finish_date=models.DateTimeField(_('End date') ,blank=True, null=True) - category=models.CharField(max_length=256, choices=TRAVEL_CATEGORY) - title=models.CharField(_('Title'), max_length=255) - transportation=models.CharField(_('Transpotation'), max_length=255 ,blank=True, null=True) - moving_distance=models.IntegerField(blank=True, null=True) - duration=models.DurationField(_('Duration') ,blank=True, null=True) - eta=models.DateTimeField(blank=True, null=True) - parammeters=models.CharField(_('Parameters'), max_length=512 ,blank=True, null=True) - created_at=models.DateTimeField(auto_now_add=True) - last_updated_user=models.ForeignKey(User, related_name="travel_list_updated_user", on_delete=models.DO_NOTHING) - last_updated_at=models.DateTimeField(auto_now=True) - - -class TravelPoint(models.Model): - travel_list= models.ForeignKey(TravelList, on_delete=models.DO_NOTHING) - location=models.ForeignKey(Location, on_delete=models.CASCADE) - distance=models.FloatField(blank=True, null=True) - transportation=models.CharField(_('Transpotation'), max_length=255 ,blank=True, null=True) - eta=models.DateTimeField(blank=True, null=True) - order_number=models.IntegerField(blank=True, null=True) - parammeters=models.CharField(_('Parameters'), max_length=512 ,blank=True, null=True) - created_at=models.DateTimeField(auto_now_add=True) - last_updated_user=models.ForeignKey(User, related_name="travelpoint_updated_user", on_delete=models.DO_NOTHING) - last_updated_at=models.DateTimeField(auto_now=True) - - - - -class RogEvent(models.Model): - title=models.CharField(_('Title'), max_length=255) - venue=models.CharField(_('Venue'), max_length=255) - at_date=models.DateTimeField(_('At Date'), auto_now_add=True) - geom=models.MultiPointField(srid=4326) - - def __str__(self): - return self.title - -class EventRoute(models.Model): - name = models.CharField(_("Name"), max_length=255) - event = models.OneToOneField(RogEvent, on_delete=models.CASCADE) - geom = models.MultiLineStringField(srid=4326) - - def __str__(self): - return self.name - - -class Shop(models.Model): - name=models.CharField(_('Shop name'), max_length=255) - geom=models.MultiPointField(srid=4326) - - def __str__(self): - return self.name - - -class ShopRoute(models.Model): - name = models.CharField(_("Name"), max_length=255) - shop = models.OneToOneField(Shop, on_delete=models.CASCADE) - geom = models.MultiLineStringField(srid=4326) - - def __str__(self): - return self.name - - -def getTableForModel(tbl): - if tbl == 1: - return Location.objects.model._meta.db_table; - elif tbl == 2: - return Location_line.objects.model._meta.db_table; - else: - return Location_polygon.objects.model._meta.db_table; - -def getMappingforModel(tbl, shp): - if tbl == 1: - return LayerMapping(Location, shp, location_mapping, transform=False) - elif tbl == 2: - return LayerMapping(Location_line, shp, location_line_mapping, transform=False) - else: - return LayerMapping(Location_polygon, shp, location_polygon_mapping, transform=False) - - -class ShapeLayers(models.Model): - name = models.CharField(_("Shape Layer"), max_length=255) - file = models.FileField(upload_to='%y%m%d', blank=True) - uploaded_date = models.DateField(auto_now_add=True) - layerof = models.IntegerField(choices=LAYER_CHOICES, default=1) - table_name = models.CharField(_("Table name"), max_length=255, blank=True) - - def __str__(self): - return self.name - - - - -@receiver(pre_save, sender=ShapeLayers) -def my_callback(sender, instance, *args, **kwargs): - instance.table_name = getTableForModel(instance.layerof) - -@receiver(post_save, sender=ShapeLayers) -def publish_date(sender, instance, created, **kwargs): - file = instance.file.path - file_format = os.path.basename(file).split('.')[-1] - file_name = os.path.basename(file).split('.')[0] - file_path = os.path.dirname(file) - name = instance.name - conn_str = f'postgresql://{env("POSTGRES_USER")}:{env("POSTGRES_PASS")}@{env("PG_HOST")}:{env("PG_PORT")}/{env("POSTGRES_DBNAME")}' - - with zipfile.ZipFile(file, 'r') as zip_ref: - zip_ref.extractall(file_path) - - os.remove(file) - - try: - shp = glob.glob(r'{}/**/*.shp'.format(file_path), recursive=True)[0] - gdf = gpd.read_file(shp) - crs_name = str(gdf.crs.srs) - print(crs_name, 'crs - name') - epsg = int(crs_name.replace('epsg:','')) - if epsg is None: - epsg=4326 - - lm2 = getMappingforModel(instance.layerof, shp) - print("### shape file is ###") - lm2.save(strict=True, verbose=True) - - os.remove(shp) - except Exception as e: - print('##################',e) - - try: - csv = glob.glob(r'{}/**/*.csv'.format(file_path), recursive=True)[0] - - mdl = apps.get_model(app_label="rog", model_name=LAYER_CHOICES[instance.layerof -1][1]) - print(mdl) - print(f"#### instance.layerof - {instance.layerof}") - with open(csv, "r") as txt_file: - lns = txt_file.readlines() - for ln in lns: - fields = ln.split(",") - if instance.layerof == 2: - updateLineTable(mdl, fields) - if instance.layerof == 3: - updatePolygonTable(mdl, fields) - - except Exception as e: - print('##################',e) - - -def updateLineTable(mdl, fields): - #print(f"Updated {fields[0]} - {fields[1]}") - mdl.objects.filter(location_id = fields[0]).update( - location_name=fields[1], - category=fields[2], - zip=fields[3], - address=fields[4], - prefecture=fields[5], - area=fields[6], - city=fields[7], - photos=fields[8], - videos=fields[9], - webcontents=fields[10], - status=fields[11], - portal=fields[12], - group=fields[13], - phone=fields[14], - fax=fields[15], - email=fields[16], - facility=fields[17], - remark=fields[18], - tags=fields[19], - parammeters=fields[20] - ) - - -def updatePolygonTable(mdl, fields): - #print(f"Updated {fields[0]} - {fields[1]}") - mdl.objects.filter(location_id = fields[0]).update( - location_name=fields[1], - category=fields[2], - zip=fields[3], - address=fields[4], - prefecture=fields[5], - area=fields[6], - city=fields[7], - photos=fields[8], - videos=fields[9], - webcontents=fields[10], - status=fields[11], - portal=fields[12], - group=fields[13], - phone=fields[14], - fax=fields[15], - email=fields[16], - facility=fields[17], - remark=fields[18], - tags=fields[19], - parammeters=fields[20] - ) +from dataclasses import field +from pyexpat import model +from sre_constants import CH_LOCALE +from typing import ChainMap +from django.contrib.gis.db import models +from django.utils.translation import gettext_lazy as _ +from django.contrib.auth.models import User +from django.db.models.signals import post_save, post_delete, pre_save +from django.dispatch import receiver +import geopandas as gpd +from sqlalchemy import * +from geoalchemy2 import Geometry, WKTElement +import os, zipfile, glob +import environ +from geo.Postgres import Db +from sqlalchemy.sql.functions import mode +from .mapping import location_mapping, location_line_mapping, location_polygon_mapping +from .choices import LAYER_CHOICES +from django.contrib.gis.utils import LayerMapping +from django.apps import apps + +env = environ.Env(DEBUG=(bool, False)) +environ.Env.read_env(env_file=".env") + +db = Db(dbname=env("POSTGRES_DBNAME"), user=env("POSTGRES_USER"), password=env("POSTGRES_PASS"), host="postgres-db", port=env("PG_PORT")) + + +class RogUser(models.Model): + user=models.OneToOneField(User, on_delete=models.CASCADE) + email=models.EmailField(_('Email')) + phone=models.CharField(_('Phone Number'), max_length=55) + first_name=models.CharField(_('First Name'), max_length=255) + middle_name=models.CharField(_('Middle Name'), max_length=255, blank=True, null=True) + last_name=models.CharField(_('last_name'), max_length=255) + nickname=models.CharField(_('Nickname'), max_length=255, blank=True, null=True) + country=models.CharField(_('Country'), max_length=255, default='Japan') + language=models.CharField(_('Language'), max_length=255, default='Japanese') + prefecture=models.CharField(_('Prefecture'), max_length=255, blank=True, null=True) + sex=models.CharField(_('Sex'), max_length=255, default='unknown', blank=True, null=True) + birthyear=models.IntegerField(_('Birth year'), blank=True, null=True) + family_structure =models.IntegerField(_('Family Structure'), blank=True, null=True) + introducer = models.ForeignKey(User, related_name='introduced_uesr', on_delete=models.DO_NOTHING) + level= models.IntegerField(_('Level'), blank=True, null=True, default=0) + parammeters=models.CharField(_('Parameters'), max_length=512) + created_at=models.DateTimeField(auto_now_add=True) + last_updated_user=models.ForeignKey(User, related_name="roguser_updated_user", on_delete=models.DO_NOTHING) + last_updated_at=models.DateTimeField(auto_now=True) + + +class SystemSettings(models.Model): + setting_name=models.CharField(_('Settings Name'), max_length=255) + version=models.CharField(_('Version'), max_length=10, blank=True, null=True) + effective_date=models.DateTimeField() + end_date=models.DateTimeField() + parammeters=models.CharField(_('Parameters'), max_length=512) + created_at=models.DateTimeField(auto_now_add=True) + last_updated_user=models.ForeignKey(User, related_name="system_setting_updated_user", on_delete=models.DO_NOTHING) + last_updated_at=models.DateTimeField(auto_now=True) + +class Location(models.Model): + location_id=models.IntegerField(_('Location id'), blank=True, null=True) + location_name=models.CharField(_('Location Name'), max_length=255) + category=models.CharField(_('Category'), max_length=255, blank=True, null=True) + zip=models.CharField(_('Zip code'), max_length=12, blank=True, null=True) + address = models.CharField(_('Address'), max_length=512, blank=True, null=True) + prefecture = models.CharField(_('Prefecture'), max_length=255, blank=True, null=True) + area= models.CharField(_('Area'), max_length=255, blank=True, null=True) + city= models.CharField(_('City'), max_length=255, blank=True, null=True) + photos=models.CharField(_('Phptos'), max_length=255, blank=True, null=True) + videos=models.CharField(_('Videos'), max_length=255, blank=True, null=True) + webcontents=models.CharField(_('Web Content'), max_length=255, blank=True, null=True) + status=models.CharField(_('Status'),max_length=255, blank=True, null=True) + portal=models.CharField(_('Portal'), max_length=255,blank=True, null=True) + group=models.CharField(_('Group'), max_length=255,blank=True, null=True) + phone=models.CharField(_('Phone'), max_length=255,blank=True, null=True) + fax=models.CharField(_('Fax'), max_length=255, blank=True, null=True) + email=models.EmailField(_('Email'), max_length=255,blank=True, null=True) + facility=models.CharField(_('Facility'), max_length=255, blank=True, null=True) + remark=models.CharField(_('Remarks'), max_length=255, blank=True, null=True) + tags=models.CharField(_('Tags'), max_length=512, blank=True, null=True) + parammeters=models.CharField(_('Parameters'), max_length=512, blank=True, null=True) + created_at=models.DateTimeField(auto_now_add=True) + last_updated_user=models.ForeignKey(User, related_name="location_updated_user", on_delete=models.DO_NOTHING,blank=True, null=True) + last_updated_at=models.DateTimeField(auto_now=True) + geom=models.MultiPointField(srid=4326) + + def __str__(self): + return self.location_name + + +class Location_line(models.Model): + location_id=models.IntegerField(_('Location id'), blank=True, null=True) + location_name=models.CharField(_('Location Name'), max_length=255) + category=models.CharField(_('Category'), max_length=255, blank=True, null=True) + zip=models.CharField(_('Zip code'), max_length=12, blank=True, null=True) + address = models.CharField(_('Address'), max_length=512, blank=True, null=True) + prefecture = models.CharField(_('Prefecture'), max_length=255, blank=True, null=True) + area= models.CharField(_('Area'), max_length=255, blank=True, null=True) + city= models.CharField(_('City'), max_length=255, blank=True, null=True) + photos=models.CharField(_('Phptos'), max_length=255, blank=True, null=True) + videos=models.CharField(_('Videos'), max_length=255, blank=True, null=True) + webcontents=models.CharField(_('Web Content'), max_length=255, blank=True, null=True) + status=models.CharField(_('Status'),max_length=255, blank=True, null=True) + portal=models.CharField(_('Portal'), max_length=255,blank=True, null=True) + group=models.CharField(_('Group'), max_length=255,blank=True, null=True) + phone=models.CharField(_('Phone'), max_length=255,blank=True, null=True) + fax=models.CharField(_('Fax'), max_length=255, blank=True, null=True) + email=models.EmailField(_('Email'), max_length=255,blank=True, null=True) + facility=models.CharField(_('Facility'), max_length=255, blank=True, null=True) + remark=models.CharField(_('Remarks'), max_length=255, blank=True, null=True) + tags=models.CharField(_('Tags'), max_length=512, blank=True, null=True) + parammeters=models.CharField(_('Parameters'), max_length=512, blank=True, null=True) + created_at=models.DateTimeField(auto_now_add=True) + last_updated_user=models.ForeignKey(User, related_name="location_line_updated_user", on_delete=models.DO_NOTHING,blank=True, null=True) + last_updated_at=models.DateTimeField(auto_now=True) + geom=models.MultiLineStringField(srid=4326, blank=True, null=True) + + def __str__(self): + return str(self.location_id) + + + +class Location_polygon(models.Model): + location_id=models.IntegerField(_('Location id'), blank=True, null=True) + location_name=models.CharField(_('Location Name'), max_length=255) + category=models.CharField(_('Category'), max_length=255, blank=True, null=True) + zip=models.CharField(_('Zip code'), max_length=12, blank=True, null=True) + address = models.CharField(_('Address'), max_length=512, blank=True, null=True) + prefecture = models.CharField(_('Prefecture'), max_length=255, blank=True, null=True) + area= models.CharField(_('Area'), max_length=255, blank=True, null=True) + city= models.CharField(_('City'), max_length=255, blank=True, null=True) + photos=models.CharField(_('Phptos'), max_length=255, blank=True, null=True) + videos=models.CharField(_('Videos'), max_length=255, blank=True, null=True) + webcontents=models.CharField(_('Web Content'), max_length=255, blank=True, null=True) + status=models.CharField(_('Status'),max_length=255, blank=True, null=True) + portal=models.CharField(_('Portal'), max_length=255,blank=True, null=True) + group=models.CharField(_('Group'), max_length=255,blank=True, null=True) + phone=models.CharField(_('Phone'), max_length=255,blank=True, null=True) + fax=models.CharField(_('Fax'), max_length=255, blank=True, null=True) + email=models.EmailField(_('Email'), max_length=255,blank=True, null=True) + facility=models.CharField(_('Facility'), max_length=255, blank=True, null=True) + remark=models.CharField(_('Remarks'), max_length=255, blank=True, null=True) + tags=models.CharField(_('Tags'), max_length=512, blank=True, null=True) + parammeters=models.CharField(_('Parameters'), max_length=512, blank=True, null=True) + created_at=models.DateTimeField(auto_now_add=True) + last_updated_user=models.ForeignKey(User, related_name="location_polygon_updated_user", on_delete=models.DO_NOTHING,blank=True, null=True) + last_updated_at=models.DateTimeField(auto_now=True) + geom=models.MultiPolygonField(srid=4326, blank=True, null=True) + + def __str__(self): + return str(self.location_name) + + + +EVENT_STATUS = ( + ("PREPARING", _("Preparing")), + ("PROMOTION", _("Promotion")), + ("EVENT", _("Event")), + ("END", _("End")) +) + + + +class Event(models.Model): + tagname=models.CharField(_('Parameters'), max_length=512, blank=True, null=True) + status=models.CharField(max_length=256, choices=EVENT_STATUS) + price=models.IntegerField(_('Paid Amount'), default=0) + promotion_date=models.DateTimeField(_('Promotion date'), blank=True, null=True) + event_start=models.DateTimeField(_('Promotion date'), blank=True, null=True) + event_end=models.DateTimeField(_('Promotion date'), blank=True, null=True) + remark=models.CharField(max_length=256, blank=True, null=True) + parammeters=models.CharField(_('Parameters'), max_length=512, blank=True, null=True) + created_at=models.DateTimeField(auto_now_add=True) + last_updated_user=models.ForeignKey(User, related_name="event_updated_user", on_delete=models.DO_NOTHING,blank=True, null=True) + last_updated_at=models.DateTimeField(auto_now=True) + + +ROG_STATUS = ( + ("REGISTERED", _("Registered")), + ("ACCEPTED", _("accepted")), + ("PAID", _("paid")), + ("JOINED", _("joined")), + ("CANCELED", _("Canceled")) +) + +class JoinedEvent(models.Model): + user=models.ForeignKey(User, on_delete=models.DO_NOTHING) + tagname=models.CharField(_('Tag Name'), max_length=255, blank=True, null=True) + status=models.CharField(max_length=256, choices=ROG_STATUS) + registrationid=models.CharField(_('Registration Id'), max_length=56) + payment_code=models.CharField(_('Payment Code'), max_length=255) + paid=models.IntegerField(_('Paid Amount'), default=0) + remark=models.CharField(_('Remark'), max_length=255, blank=True, null=True) + parammeters=models.CharField(_('Parameters'), max_length=512) + created_at=models.DateTimeField(auto_now_add=True) + last_updated_user=models.ForeignKey(User, related_name="joined_event_updated_user", on_delete=models.DO_NOTHING) + last_updated_at=models.DateTimeField(auto_now=True) + + + +class Favorite(models.Model): + user=models.ForeignKey(User, on_delete=models.DO_NOTHING) + location=models.ForeignKey(Location, on_delete=models.CASCADE) + good=models.IntegerField(_('Good'), default=0) + favorite=models.IntegerField(_('Favorite'), default=0) + evaluation=models.IntegerField(_('Evaluation'), default=0) + number_visit=models.IntegerField(_('Good'), default=0) + last_visited=models.DateTimeField(_('Last Visited'), blank=True, null=True) + parammeters=models.CharField(_('Parameters'), max_length=512, blank=True, null=True) + created_at=models.DateTimeField(auto_now_add=True) + last_updated_user=models.ForeignKey(User, related_name="favorite_updated_user", on_delete=models.DO_NOTHING) + last_updated_at=models.DateTimeField(auto_now=True) + + + +TRAVEL_CATEGORY = ( + ("PRIVATE", _("Private")), + ("GROUP", _("Group")), + ("AGENT", _("Agent")), + ("ROGAINING", _("Rogaining")) +) + + + +class TravelList(models.Model): + travel_id= models.IntegerField(_('Travel Id')) + user=models.ForeignKey(User, on_delete=models.DO_NOTHING) + start_date=models.DateTimeField(_('Start date') ,blank=True, null=True) + finish_date=models.DateTimeField(_('End date') ,blank=True, null=True) + category=models.CharField(max_length=256, choices=TRAVEL_CATEGORY) + title=models.CharField(_('Title'), max_length=255) + transportation=models.CharField(_('Transpotation'), max_length=255 ,blank=True, null=True) + moving_distance=models.IntegerField(blank=True, null=True) + duration=models.DurationField(_('Duration') ,blank=True, null=True) + eta=models.DateTimeField(blank=True, null=True) + parammeters=models.CharField(_('Parameters'), max_length=512 ,blank=True, null=True) + created_at=models.DateTimeField(auto_now_add=True) + last_updated_user=models.ForeignKey(User, related_name="travel_list_updated_user", on_delete=models.DO_NOTHING) + last_updated_at=models.DateTimeField(auto_now=True) + + +class TravelPoint(models.Model): + travel_list= models.ForeignKey(TravelList, on_delete=models.DO_NOTHING) + location=models.ForeignKey(Location, on_delete=models.CASCADE) + distance=models.FloatField(blank=True, null=True) + transportation=models.CharField(_('Transpotation'), max_length=255 ,blank=True, null=True) + eta=models.DateTimeField(blank=True, null=True) + order_number=models.IntegerField(blank=True, null=True) + parammeters=models.CharField(_('Parameters'), max_length=512 ,blank=True, null=True) + created_at=models.DateTimeField(auto_now_add=True) + last_updated_user=models.ForeignKey(User, related_name="travelpoint_updated_user", on_delete=models.DO_NOTHING) + last_updated_at=models.DateTimeField(auto_now=True) + + + + +class RogEvent(models.Model): + title=models.CharField(_('Title'), max_length=255) + venue=models.CharField(_('Venue'), max_length=255) + at_date=models.DateTimeField(_('At Date'), auto_now_add=True) + geom=models.MultiPointField(srid=4326) + + def __str__(self): + return self.title + +class EventRoute(models.Model): + name = models.CharField(_("Name"), max_length=255) + event = models.OneToOneField(RogEvent, on_delete=models.CASCADE) + geom = models.MultiLineStringField(srid=4326) + + def __str__(self): + return self.name + + +class Shop(models.Model): + name=models.CharField(_('Shop name'), max_length=255) + geom=models.MultiPointField(srid=4326) + + def __str__(self): + return self.name + + +class ShopRoute(models.Model): + name = models.CharField(_("Name"), max_length=255) + shop = models.OneToOneField(Shop, on_delete=models.CASCADE) + geom = models.MultiLineStringField(srid=4326) + + def __str__(self): + return self.name + + +def getTableForModel(tbl): + if tbl == 1: + return Location.objects.model._meta.db_table; + elif tbl == 2: + return Location_line.objects.model._meta.db_table; + else: + return Location_polygon.objects.model._meta.db_table; + +def getMappingforModel(tbl, shp): + if tbl == 1: + return LayerMapping(Location, shp, location_mapping, transform=False) + elif tbl == 2: + return LayerMapping(Location_line, shp, location_line_mapping, transform=False) + else: + return LayerMapping(Location_polygon, shp, location_polygon_mapping, transform=False) + + +class ShapeLayers(models.Model): + name = models.CharField(_("Shape Layer"), max_length=255) + file = models.FileField(upload_to='%y%m%d', blank=True) + uploaded_date = models.DateField(auto_now_add=True) + layerof = models.IntegerField(choices=LAYER_CHOICES, default=1) + table_name = models.CharField(_("Table name"), max_length=255, blank=True) + + def __str__(self): + return self.name + + + + +@receiver(pre_save, sender=ShapeLayers) +def my_callback(sender, instance, *args, **kwargs): + instance.table_name = getTableForModel(instance.layerof) + +@receiver(post_save, sender=ShapeLayers) +def publish_date(sender, instance, created, **kwargs): + file = instance.file.path + file_format = os.path.basename(file).split('.')[-1] + file_name = os.path.basename(file).split('.')[0] + file_path = os.path.dirname(file) + name = instance.name + conn_str = f'postgresql://{env("POSTGRES_USER")}:{env("POSTGRES_PASS")}@{env("PG_HOST")}:{env("PG_PORT")}/{env("POSTGRES_DBNAME")}' + + with zipfile.ZipFile(file, 'r') as zip_ref: + zip_ref.extractall(file_path) + + os.remove(file) + + try: + shp = glob.glob(r'{}/**/*.shp'.format(file_path), recursive=True)[0] + gdf = gpd.read_file(shp) + crs_name = str(gdf.crs.srs) + print(crs_name, 'crs - name') + epsg = int(crs_name.replace('epsg:','')) + if epsg is None: + epsg=4326 + + lm2 = getMappingforModel(instance.layerof, shp) + print("### shape file is ###") + lm2.save(strict=True, verbose=True) + + os.remove(shp) + except Exception as e: + print('##################',e) + + try: + csv = glob.glob(r'{}/**/*.csv'.format(file_path), recursive=True)[0] + + mdl = apps.get_model(app_label="rog", model_name=LAYER_CHOICES[instance.layerof -1][1]) + print(mdl) + print(f"#### instance.layerof - {instance.layerof}") + with open(csv, "r") as txt_file: + lns = txt_file.readlines() + for ln in lns: + fields = ln.split(",") + if instance.layerof == 2: + updateLineTable(mdl, fields) + if instance.layerof == 3: + updatePolygonTable(mdl, fields) + + except Exception as e: + print('##################',e) + + +def updateLineTable(mdl, fields): + #print(f"Updated {fields[0]} - {fields[1]}") + mdl.objects.filter(location_id = fields[0]).update( + location_name=fields[1], + category=fields[2], + zip=fields[3], + address=fields[4], + prefecture=fields[5], + area=fields[6], + city=fields[7], + photos=fields[8], + videos=fields[9], + webcontents=fields[10], + status=fields[11], + portal=fields[12], + group=fields[13], + phone=fields[14], + fax=fields[15], + email=fields[16], + facility=fields[17], + remark=fields[18], + tags=fields[19], + parammeters=fields[20] + ) + + +def updatePolygonTable(mdl, fields): + #print(f"Updated {fields[0]} - {fields[1]}") + mdl.objects.filter(location_id = fields[0]).update( + location_name=fields[1], + category=fields[2], + zip=fields[3], + address=fields[4], + prefecture=fields[5], + area=fields[6], + city=fields[7], + photos=fields[8], + videos=fields[9], + webcontents=fields[10], + status=fields[11], + portal=fields[12], + group=fields[13], + phone=fields[14], + fax=fields[15], + email=fields[16], + facility=fields[17], + remark=fields[18], + tags=fields[19], + parammeters=fields[20] + ) diff --git a/rog/serializers.py b/rog/serializers.py index b53aaa2..71c22da 100644 --- a/rog/serializers.py +++ b/rog/serializers.py @@ -1,32 +1,52 @@ -from rest_framework_gis.serializers import GeoFeatureModelSerializer -from sqlalchemy.sql.functions import mode -from .models import RogEvent, Shop, EventRoute, ShopRoute -from drf_extra_fields.fields import Base64ImageField - - -class RogEventSerializer(GeoFeatureModelSerializer): - class Meta: - model=RogEvent - geo_field="geom" - fields="__all__" - - -class ShopSerializer(GeoFeatureModelSerializer): - class Meta: - model=Shop - geo_field="geom" - fields="__all__" - - -class EventRouteSerializer(GeoFeatureModelSerializer): - class Meta: - model=EventRoute - geo_field="geom" - fields="__all__" - - -class ShopRouteSerializer(GeoFeatureModelSerializer): - class Meta: - model=ShopRoute - geo_field="geom" +from rest_framework_gis.serializers import GeoFeatureModelSerializer +from sqlalchemy.sql.functions import mode +from .models import RogEvent, Shop, EventRoute, ShopRoute, Location, Location_line, Location_polygon +from drf_extra_fields.fields import Base64ImageField + + +class LocationSerializer(GeoFeatureModelSerializer): + class Meta: + model=Location + geo_field='geom' + fields="__all__" + + +class Location_lineSerializer(GeoFeatureModelSerializer): + class Meta: + model=Location_line + geo_field='geom' + fields="__all__" + +class Location_polygonSerializer(GeoFeatureModelSerializer): + class Meta: + model=Location_polygon + geo_field='geom' + fields="__all__" + + +class RogEventSerializer(GeoFeatureModelSerializer): + class Meta: + model=RogEvent + geo_field="geom" + fields="__all__" + + +class ShopSerializer(GeoFeatureModelSerializer): + class Meta: + model=Shop + geo_field="geom" + fields="__all__" + + +class EventRouteSerializer(GeoFeatureModelSerializer): + class Meta: + model=EventRoute + geo_field="geom" + fields="__all__" + + +class ShopRouteSerializer(GeoFeatureModelSerializer): + class Meta: + model=ShopRoute + geo_field="geom" fields="__all__" \ No newline at end of file diff --git a/rog/tests.py b/rog/tests.py index 7ce503c..de8bdc0 100644 --- a/rog/tests.py +++ b/rog/tests.py @@ -1,3 +1,3 @@ -from django.test import TestCase - -# Create your tests here. +from django.test import TestCase + +# Create your tests here. diff --git a/rog/urls.py b/rog/urls.py index 7df2325..753541d 100644 --- a/rog/urls.py +++ b/rog/urls.py @@ -1,14 +1,18 @@ -from rest_framework import urlpatterns -from rest_framework.routers import DefaultRouter -from .views import RogEventViewSet, EventRouteViewSet, ShopViewSet, ShopRouteViewSet -from django.urls import path, include - - -router = DefaultRouter() - -router.register(prefix='v1/rog', viewset=RogEventViewSet, basename='rog') -router.register(prefix='v1/eventroute', viewset=EventRouteViewSet, basename='eventroute') -router.register(prefix='v1/shop', viewset=ShopViewSet, basename='shop') -router.register(prefix='v1/shoproute', viewset=ShopRouteViewSet, basename='shoproute') - -urlpatterns = router.urls +from rest_framework import urlpatterns +from rest_framework.routers import DefaultRouter +from .views import RogEventViewSet, EventRouteViewSet, ShopViewSet, ShopRouteViewSet, LocationViewSet, Location_lineViewSet, Location_polygonViewSet +from django.urls import path, include + + +router = DefaultRouter() + +router.register(prefix='location', viewset=LocationViewSet, basename='location') +router.register(prefix='location_line', viewset=Location_lineViewSet, basename="location_line") +router.register(prefix='location_polygon', viewset=Location_polygonViewSet, basename='location_polygon') + +router.register(prefix='v1/rog', viewset=RogEventViewSet, basename='rog') +router.register(prefix='v1/eventroute', viewset=EventRouteViewSet, basename='eventroute') +router.register(prefix='v1/shop', viewset=ShopViewSet, basename='shop') +router.register(prefix='v1/shoproute', viewset=ShopRouteViewSet, basename='shoproute') + +urlpatterns = router.urls diff --git a/rog/views.py b/rog/views.py index d55587c..8e132d6 100644 --- a/rog/views.py +++ b/rog/views.py @@ -1,31 +1,45 @@ -from django.core.serializers import serialize -from .models import RogEvent, ShopRoute, EventRoute, Shop -from rest_framework import viewsets -from .serializers import RogEventSerializer, EventRouteSerializer, ShopSerializer, ShopRouteSerializer -from rest_framework.decorators import action -from rest_framework.response import Response -from rest_framework.parsers import JSONParser, MultiPartParser - - - - - -class RogEventViewSet(viewsets.ModelViewSet): - queryset=RogEvent.objects.all() - serializer_class=RogEventSerializer - - -class EventRouteViewSet(viewsets.ModelViewSet): - queryset=EventRoute.objects.all() - serializer_class=EventRouteSerializer - - -class ShopViewSet(viewsets.ModelViewSet): - queryset=Shop.objects.all() - serializer_class=ShopSerializer - - -class ShopRouteViewSet(viewsets.ModelViewSet): - queryset=ShopRoute.objects.all() - serializer_class=ShopRouteSerializer - +from django.core.serializers import serialize +from .models import RogEvent, ShopRoute, EventRoute, Shop, Location, Location_line, Location_polygon +from rest_framework import viewsets +from .serializers import RogEventSerializer, EventRouteSerializer, ShopSerializer, ShopRouteSerializer, LocationSerializer, Location_lineSerializer, Location_polygonSerializer +from rest_framework.decorators import action +from rest_framework.response import Response +from rest_framework.parsers import JSONParser, MultiPartParser + + + +class LocationViewSet(viewsets.ModelViewSet): + queryset=Location.objects.all() + serializer_class=LocationSerializer + + +class Location_lineViewSet(viewsets.ModelViewSet): + queryset=Location_line.objects.all() + serializer_class=Location_lineSerializer + + +class Location_polygonViewSet(viewsets.ModelViewSet): + queryset=Location_polygon.objects.all() + serializer_class=Location_polygonSerializer + + + +class RogEventViewSet(viewsets.ModelViewSet): + queryset=RogEvent.objects.all() + serializer_class=RogEventSerializer + + +class EventRouteViewSet(viewsets.ModelViewSet): + queryset=EventRoute.objects.all() + serializer_class=EventRouteSerializer + + +class ShopViewSet(viewsets.ModelViewSet): + queryset=Shop.objects.all() + serializer_class=ShopSerializer + + +class ShopRouteViewSet(viewsets.ModelViewSet): + queryset=ShopRoute.objects.all() + serializer_class=ShopRouteSerializer +