Compare commits
25 Commits
exdb
...
338643b0d7
| Author | SHA1 | Date | |
|---|---|---|---|
| 338643b0d7 | |||
| e992e834da | |||
| c6969d7afa | |||
| 82d0e55945 | |||
| b872f377b2 | |||
| a6b816c9f2 | |||
| 2913a435c1 | |||
| 051916f9f6 | |||
| b8d7029965 | |||
| 6f0d8d15fd | |||
| 80ccaace3d | |||
| 95b787c819 | |||
| 3d195973fc | |||
| d851e7e4ad | |||
| 9d0d3ea102 | |||
| 37a253e63a | |||
| bc74b14cbc | |||
| 49b3ee7342 | |||
| 26e8e68dbd | |||
| 44ad30093c | |||
| bcfcceb068 | |||
| 9215ba8f9f | |||
| c0fb177d02 | |||
| 09e39987e2 | |||
| 6f79d9a4be |
6
.gitignore
vendored
6
.gitignore
vendored
@ -157,6 +157,10 @@ dmypy.json
|
|||||||
# Cython debug symbols
|
# Cython debug symbols
|
||||||
cython_debug/
|
cython_debug/
|
||||||
|
|
||||||
|
# migration files
|
||||||
|
rog/migrations/
|
||||||
|
|
||||||
|
|
||||||
# PyCharm
|
# PyCharm
|
||||||
# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can
|
# 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
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
@ -165,4 +169,4 @@ cython_debug/
|
|||||||
#.idea/
|
#.idea/
|
||||||
|
|
||||||
# End of https://www.toptal.com/developers/gitignore/api/django
|
# End of https://www.toptal.com/developers/gitignore/api/django
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
@ -51,7 +51,10 @@ RUN pip install gunicorn
|
|||||||
|
|
||||||
#RUN ["chmod", "+x", "wait-for.sh"]
|
#RUN ["chmod", "+x", "wait-for.sh"]
|
||||||
|
|
||||||
RUN pip install -r requirements.txt
|
# xlsxwriterを追加
|
||||||
|
RUN pip install -r requirements.txt \
|
||||||
|
&& pip install django-cors-headers \
|
||||||
|
&& pip install xlsxwriter gunicorn
|
||||||
|
|
||||||
COPY . /app
|
COPY . /app
|
||||||
|
|
||||||
|
|||||||
35
Dockerfile.supervisor
Normal file
35
Dockerfile.supervisor
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
FROM nginx:alpine
|
||||||
|
|
||||||
|
# Create necessary directories and set permissions
|
||||||
|
RUN mkdir -p /usr/share/nginx/html \
|
||||||
|
&& mkdir -p /var/log/nginx \
|
||||||
|
&& mkdir -p /var/cache/nginx \
|
||||||
|
&& chown -R nginx:nginx /usr/share/nginx/html \
|
||||||
|
&& chown -R nginx:nginx /var/log/nginx \
|
||||||
|
&& chown -R nginx:nginx /var/cache/nginx \
|
||||||
|
&& chmod -R 755 /usr/share/nginx/html
|
||||||
|
|
||||||
|
# Copy files - notice the change in the source path
|
||||||
|
COPY supervisor/html/* /usr/share/nginx/html/
|
||||||
|
COPY supervisor/nginx/default.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
# メディアディレクトリを作成
|
||||||
|
RUN mkdir -p /app/media && chmod 755 /app/media
|
||||||
|
|
||||||
|
# 静的ファイルをコピー
|
||||||
|
#COPY ./static /usr/share/nginx/html/static
|
||||||
|
|
||||||
|
# 権限の設定
|
||||||
|
RUN chown -R nginx:nginx /app/media
|
||||||
|
|
||||||
|
# Set final permissions
|
||||||
|
RUN chown -R nginx:nginx /usr/share/nginx/html \
|
||||||
|
&& chmod -R 755 /usr/share/nginx/html \
|
||||||
|
&& touch /var/log/nginx/access.log \
|
||||||
|
&& touch /var/log/nginx/error.log \
|
||||||
|
&& chown -R nginx:nginx /var/log/nginx \
|
||||||
|
&& chown -R nginx:nginx /etc/nginx/conf.d
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
19
SumasenLibs/excel_lib/README.md
Normal file
19
SumasenLibs/excel_lib/README.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# SumasenExcel Library
|
||||||
|
|
||||||
|
Excel操作のためのシンプルなPythonライブラリです。
|
||||||
|
|
||||||
|
## インストール方法
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install -e .
|
||||||
|
|
||||||
|
## 使用方法
|
||||||
|
from sumaexcel import SumasenExcel
|
||||||
|
|
||||||
|
excel = SumasenExcel("path/to/file.xlsx")
|
||||||
|
data = excel.read_excel()
|
||||||
|
|
||||||
|
## ライセンス
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
14
SumasenLibs/excel_lib/docker/docker-compose.yml
Normal file
14
SumasenLibs/excel_lib/docker/docker-compose.yml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
python:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: docker/python/Dockerfile
|
||||||
|
volumes:
|
||||||
|
- ..:/app
|
||||||
|
environment:
|
||||||
|
- PYTHONPATH=/app
|
||||||
|
command: /bin/bash
|
||||||
|
tty: true
|
||||||
|
|
||||||
27
SumasenLibs/excel_lib/docker/python/Dockerfile
Normal file
27
SumasenLibs/excel_lib/docker/python/Dockerfile
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
FROM python:3.9-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 必要なシステムパッケージのインストール
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
git \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Pythonパッケージのインストール
|
||||||
|
COPY requirements.txt .
|
||||||
|
COPY setup.py .
|
||||||
|
COPY README.md .
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# 開発用パッケージのインストール
|
||||||
|
RUN pip install --no-cache-dir \
|
||||||
|
pytest \
|
||||||
|
pytest-cov \
|
||||||
|
flake8
|
||||||
|
|
||||||
|
|
||||||
|
# パッケージのインストール
|
||||||
|
RUN pip install -e .
|
||||||
|
|
||||||
5
SumasenLibs/excel_lib/requirements.txt
Normal file
5
SumasenLibs/excel_lib/requirements.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
openpyxl>=3.0.0
|
||||||
|
pandas>=1.0.0
|
||||||
|
pillow>=8.0.0
|
||||||
|
configparser>=5.0.0
|
||||||
|
|
||||||
25
SumasenLibs/excel_lib/setup.py
Normal file
25
SumasenLibs/excel_lib/setup.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# setup.py
|
||||||
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name="sumaexcel",
|
||||||
|
version="0.1.0",
|
||||||
|
packages=find_packages(),
|
||||||
|
install_requires=[
|
||||||
|
"openpyxl>=3.0.0",
|
||||||
|
"pandas>=1.0.0"
|
||||||
|
],
|
||||||
|
author="Akira Miyata",
|
||||||
|
author_email="akira.miyata@sumasen.net",
|
||||||
|
description="Excel handling library",
|
||||||
|
long_description=open("README.md").read(),
|
||||||
|
long_description_content_type="text/markdown",
|
||||||
|
url="https://github.com/akiramiyata/sumaexcel",
|
||||||
|
classifiers=[
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"License :: OSI Approved :: MIT License",
|
||||||
|
"Operating System :: OS Independent",
|
||||||
|
],
|
||||||
|
python_requires=">=3.6",
|
||||||
|
)
|
||||||
|
|
||||||
4
SumasenLibs/excel_lib/sumaexcel/__init__.py
Normal file
4
SumasenLibs/excel_lib/sumaexcel/__init__.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
from .sumaexcel import SumasenExcel
|
||||||
|
|
||||||
|
__version__ = "0.1.0"
|
||||||
|
__all__ = ["SumasenExcel"]
|
||||||
102
SumasenLibs/excel_lib/sumaexcel/conditional.py
Normal file
102
SumasenLibs/excel_lib/sumaexcel/conditional.py
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
# sumaexcel/conditional.py
|
||||||
|
from typing import Dict, Any, List, Union
|
||||||
|
from openpyxl.formatting.rule import Rule, ColorScaleRule, DataBarRule, IconSetRule
|
||||||
|
from openpyxl.styles import PatternFill, Font, Border, Side
|
||||||
|
from openpyxl.worksheet.worksheet import Worksheet
|
||||||
|
|
||||||
|
class ConditionalFormatManager:
|
||||||
|
"""Handle conditional formatting in Excel"""
|
||||||
|
|
||||||
|
def __init__(self, worksheet: Worksheet):
|
||||||
|
self.worksheet = worksheet
|
||||||
|
|
||||||
|
def add_color_scale(
|
||||||
|
self,
|
||||||
|
cell_range: str,
|
||||||
|
min_color: str = "00FF0000", # Red
|
||||||
|
mid_color: str = "00FFFF00", # Yellow
|
||||||
|
max_color: str = "0000FF00" # Green
|
||||||
|
) -> None:
|
||||||
|
"""Add color scale conditional formatting"""
|
||||||
|
rule = ColorScaleRule(
|
||||||
|
start_type='min',
|
||||||
|
start_color=min_color,
|
||||||
|
mid_type='percentile',
|
||||||
|
mid_value=50,
|
||||||
|
mid_color=mid_color,
|
||||||
|
end_type='max',
|
||||||
|
end_color=max_color
|
||||||
|
)
|
||||||
|
self.worksheet.conditional_formatting.add(cell_range, rule)
|
||||||
|
|
||||||
|
def add_data_bar(
|
||||||
|
self,
|
||||||
|
cell_range: str,
|
||||||
|
color: str = "000000FF", # Blue
|
||||||
|
show_value: bool = True
|
||||||
|
) -> None:
|
||||||
|
"""Add data bar conditional formatting"""
|
||||||
|
rule = DataBarRule(
|
||||||
|
start_type='min',
|
||||||
|
end_type='max',
|
||||||
|
color=color,
|
||||||
|
showValue=show_value
|
||||||
|
)
|
||||||
|
self.worksheet.conditional_formatting.add(cell_range, rule)
|
||||||
|
|
||||||
|
def add_icon_set(
|
||||||
|
self,
|
||||||
|
cell_range: str,
|
||||||
|
icon_style: str = '3Arrows', # '3Arrows', '3TrafficLights', '3Signs'
|
||||||
|
reverse_icons: bool = False
|
||||||
|
) -> None:
|
||||||
|
"""Add icon set conditional formatting"""
|
||||||
|
rule = IconSetRule(
|
||||||
|
icon_style=icon_style,
|
||||||
|
type='percent',
|
||||||
|
values=[0, 33, 67],
|
||||||
|
reverse_icons=reverse_icons
|
||||||
|
)
|
||||||
|
self.worksheet.conditional_formatting.add(cell_range, rule)
|
||||||
|
|
||||||
|
def add_custom_rule(
|
||||||
|
self,
|
||||||
|
cell_range: str,
|
||||||
|
rule_type: str,
|
||||||
|
formula: str,
|
||||||
|
fill_color: str = None,
|
||||||
|
font_color: str = None,
|
||||||
|
bold: bool = None,
|
||||||
|
border_style: str = None,
|
||||||
|
border_color: str = None
|
||||||
|
) -> None:
|
||||||
|
"""Add custom conditional formatting rule"""
|
||||||
|
dxf = {}
|
||||||
|
if fill_color:
|
||||||
|
dxf['fill'] = PatternFill(start_color=fill_color, end_color=fill_color)
|
||||||
|
if font_color or bold is not None:
|
||||||
|
dxf['font'] = Font(color=font_color, bold=bold)
|
||||||
|
if border_style and border_color:
|
||||||
|
side = Side(style=border_style, color=border_color)
|
||||||
|
dxf['border'] = Border(left=side, right=side, top=side, bottom=side)
|
||||||
|
|
||||||
|
rule = Rule(type=rule_type, formula=[formula], dxf=dxf)
|
||||||
|
self.worksheet.conditional_formatting.add(cell_range, rule)
|
||||||
|
|
||||||
|
def copy_conditional_format(
|
||||||
|
self,
|
||||||
|
source_range: str,
|
||||||
|
target_range: str
|
||||||
|
) -> None:
|
||||||
|
"""Copy conditional formatting from one range to another"""
|
||||||
|
source_rules = self.worksheet.conditional_formatting.get(source_range)
|
||||||
|
if source_rules:
|
||||||
|
for rule in source_rules:
|
||||||
|
self.worksheet.conditional_formatting.add(target_range, rule)
|
||||||
|
|
||||||
|
def clear_conditional_format(
|
||||||
|
self,
|
||||||
|
cell_range: str
|
||||||
|
) -> None:
|
||||||
|
"""Clear conditional formatting from specified range"""
|
||||||
|
self.worksheet.conditional_formatting.delete(cell_range)
|
||||||
77
SumasenLibs/excel_lib/sumaexcel/image.py
Normal file
77
SumasenLibs/excel_lib/sumaexcel/image.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
# sumaexcel/image.py
|
||||||
|
from typing import Optional, Tuple, Union
|
||||||
|
from pathlib import Path
|
||||||
|
import os
|
||||||
|
from PIL import Image
|
||||||
|
from openpyxl.drawing.image import Image as XLImage
|
||||||
|
from openpyxl.worksheet.worksheet import Worksheet
|
||||||
|
|
||||||
|
class ImageManager:
|
||||||
|
"""Handle image operations in Excel"""
|
||||||
|
|
||||||
|
def __init__(self, worksheet: Worksheet):
|
||||||
|
self.worksheet = worksheet
|
||||||
|
self.temp_dir = Path("/tmp/sumaexcel_images")
|
||||||
|
self.temp_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
def add_image(
|
||||||
|
self,
|
||||||
|
image_path: Union[str, Path],
|
||||||
|
cell_coordinates: Tuple[int, int],
|
||||||
|
size: Optional[Tuple[int, int]] = None,
|
||||||
|
keep_aspect_ratio: bool = True,
|
||||||
|
anchor_type: str = 'absolute'
|
||||||
|
) -> None:
|
||||||
|
"""Add image to worksheet at specified position"""
|
||||||
|
# Convert path to Path object
|
||||||
|
image_path = Path(image_path)
|
||||||
|
|
||||||
|
# Open and process image
|
||||||
|
with Image.open(image_path) as img:
|
||||||
|
# Get original size
|
||||||
|
orig_width, orig_height = img.size
|
||||||
|
|
||||||
|
# Calculate new size if specified
|
||||||
|
if size:
|
||||||
|
target_width, target_height = size
|
||||||
|
if keep_aspect_ratio:
|
||||||
|
ratio = min(target_width/orig_width, target_height/orig_height)
|
||||||
|
target_width = int(orig_width * ratio)
|
||||||
|
target_height = int(orig_height * ratio)
|
||||||
|
|
||||||
|
# Resize image
|
||||||
|
img = img.resize((target_width, target_height), Image.LANCZOS)
|
||||||
|
|
||||||
|
# Save temporary resized image
|
||||||
|
temp_path = self.temp_dir / f"temp_{image_path.name}"
|
||||||
|
img.save(temp_path)
|
||||||
|
image_path = temp_path
|
||||||
|
|
||||||
|
# Create Excel image object
|
||||||
|
excel_image = XLImage(str(image_path))
|
||||||
|
|
||||||
|
# Add to worksheet
|
||||||
|
self.worksheet.add_image(excel_image, anchor=f'{cell_coordinates[0]}{cell_coordinates[1]}')
|
||||||
|
|
||||||
|
def add_image_absolute(
|
||||||
|
self,
|
||||||
|
image_path: Union[str, Path],
|
||||||
|
position: Tuple[int, int],
|
||||||
|
size: Optional[Tuple[int, int]] = None
|
||||||
|
) -> None:
|
||||||
|
"""Add image with absolute positioning"""
|
||||||
|
excel_image = XLImage(str(image_path))
|
||||||
|
if size:
|
||||||
|
excel_image.width, excel_image.height = size
|
||||||
|
excel_image.anchor = 'absolute'
|
||||||
|
excel_image.top, excel_image.left = position
|
||||||
|
self.worksheet.add_image(excel_image)
|
||||||
|
|
||||||
|
def cleanup(self) -> None:
|
||||||
|
"""Clean up temporary files"""
|
||||||
|
for file in self.temp_dir.glob("temp_*"):
|
||||||
|
file.unlink()
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
"""Cleanup on object destruction"""
|
||||||
|
self.cleanup()
|
||||||
96
SumasenLibs/excel_lib/sumaexcel/merge.py
Normal file
96
SumasenLibs/excel_lib/sumaexcel/merge.py
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
# sumaexcel/merge.py
|
||||||
|
from typing import List, Tuple, Dict
|
||||||
|
from openpyxl.worksheet.worksheet import Worksheet
|
||||||
|
from openpyxl.worksheet.merge import MergedCellRange
|
||||||
|
|
||||||
|
class MergeManager:
|
||||||
|
"""Handle merge cell operations"""
|
||||||
|
|
||||||
|
def __init__(self, worksheet: Worksheet):
|
||||||
|
self.worksheet = worksheet
|
||||||
|
self._merged_ranges: List[MergedCellRange] = []
|
||||||
|
self._load_merged_ranges()
|
||||||
|
|
||||||
|
def _load_merged_ranges(self) -> None:
|
||||||
|
"""Load existing merged ranges from worksheet"""
|
||||||
|
self._merged_ranges = list(self.worksheet.merged_cells.ranges)
|
||||||
|
|
||||||
|
def merge_cells(
|
||||||
|
self,
|
||||||
|
start_row: int,
|
||||||
|
start_col: int,
|
||||||
|
end_row: int,
|
||||||
|
end_col: int
|
||||||
|
) -> None:
|
||||||
|
"""Merge cells in specified range"""
|
||||||
|
self.worksheet.merge_cells(
|
||||||
|
start_row=start_row,
|
||||||
|
start_column=start_col,
|
||||||
|
end_row=end_row,
|
||||||
|
end_column=end_col
|
||||||
|
)
|
||||||
|
self._load_merged_ranges()
|
||||||
|
|
||||||
|
def unmerge_cells(
|
||||||
|
self,
|
||||||
|
start_row: int,
|
||||||
|
start_col: int,
|
||||||
|
end_row: int,
|
||||||
|
end_col: int
|
||||||
|
) -> None:
|
||||||
|
"""Unmerge cells in specified range"""
|
||||||
|
self.worksheet.unmerge_cells(
|
||||||
|
start_row=start_row,
|
||||||
|
start_column=start_col,
|
||||||
|
end_row=end_row,
|
||||||
|
end_column=end_col
|
||||||
|
)
|
||||||
|
self._load_merged_ranges()
|
||||||
|
|
||||||
|
def copy_merged_cells(
|
||||||
|
self,
|
||||||
|
source_range: Tuple[int, int, int, int],
|
||||||
|
target_start_row: int,
|
||||||
|
target_start_col: int
|
||||||
|
) -> None:
|
||||||
|
"""Copy merged cells from source range to target position"""
|
||||||
|
src_row1, src_col1, src_row2, src_col2 = source_range
|
||||||
|
row_offset = target_start_row - src_row1
|
||||||
|
col_offset = target_start_col - src_col1
|
||||||
|
|
||||||
|
for merged_range in self._merged_ranges:
|
||||||
|
if (src_row1 <= merged_range.min_row <= src_row2 and
|
||||||
|
src_col1 <= merged_range.min_col <= src_col2):
|
||||||
|
new_row1 = merged_range.min_row + row_offset
|
||||||
|
new_col1 = merged_range.min_col + col_offset
|
||||||
|
new_row2 = merged_range.max_row + row_offset
|
||||||
|
new_col2 = merged_range.max_col + col_offset
|
||||||
|
|
||||||
|
self.merge_cells(new_row1, new_col1, new_row2, new_col2)
|
||||||
|
|
||||||
|
def shift_merged_cells(
|
||||||
|
self,
|
||||||
|
start_row: int,
|
||||||
|
rows: int = 0,
|
||||||
|
cols: int = 0
|
||||||
|
) -> None:
|
||||||
|
"""Shift merged cells by specified number of rows and columns"""
|
||||||
|
new_ranges = []
|
||||||
|
for merged_range in self._merged_ranges:
|
||||||
|
if merged_range.min_row >= start_row:
|
||||||
|
new_row1 = merged_range.min_row + rows
|
||||||
|
new_col1 = merged_range.min_col + cols
|
||||||
|
new_row2 = merged_range.max_row + rows
|
||||||
|
new_col2 = merged_range.max_col + cols
|
||||||
|
|
||||||
|
self.worksheet.unmerge_cells(
|
||||||
|
start_row=merged_range.min_row,
|
||||||
|
start_column=merged_range.min_col,
|
||||||
|
end_row=merged_range.max_row,
|
||||||
|
end_column=merged_range.max_col
|
||||||
|
)
|
||||||
|
|
||||||
|
new_ranges.append((new_row1, new_col1, new_row2, new_col2))
|
||||||
|
|
||||||
|
for new_range in new_ranges:
|
||||||
|
self.merge_cells(*new_range)
|
||||||
148
SumasenLibs/excel_lib/sumaexcel/page.py
Normal file
148
SumasenLibs/excel_lib/sumaexcel/page.py
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
# sumaexcel/page.py
|
||||||
|
from typing import Optional, Dict, Any, Union
|
||||||
|
from openpyxl.worksheet.worksheet import Worksheet
|
||||||
|
from openpyxl.worksheet.page import PageMargins, PrintPageSetup
|
||||||
|
|
||||||
|
# sumaexcel/page.py (continued)
|
||||||
|
|
||||||
|
class PageManager:
|
||||||
|
"""Handle page setup and header/footer settings"""
|
||||||
|
|
||||||
|
def __init__(self, worksheet: Worksheet):
|
||||||
|
self.worksheet = worksheet
|
||||||
|
|
||||||
|
def set_page_setup(
|
||||||
|
self,
|
||||||
|
orientation: str = 'portrait',
|
||||||
|
paper_size: int = 9, # A4
|
||||||
|
fit_to_height: Optional[int] = None,
|
||||||
|
fit_to_width: Optional[int] = None,
|
||||||
|
scale: Optional[int] = None
|
||||||
|
) -> None:
|
||||||
|
"""Configure page setup
|
||||||
|
|
||||||
|
Args:
|
||||||
|
orientation: 'portrait' or 'landscape'
|
||||||
|
paper_size: paper size (e.g., 9 for A4)
|
||||||
|
fit_to_height: number of pages tall
|
||||||
|
fit_to_width: number of pages wide
|
||||||
|
scale: zoom scale (1-400)
|
||||||
|
"""
|
||||||
|
setup = PrintPageSetup(
|
||||||
|
orientation=orientation,
|
||||||
|
paperSize=paper_size,
|
||||||
|
scale=scale,
|
||||||
|
fitToHeight=fit_to_height,
|
||||||
|
fitToWidth=fit_to_width
|
||||||
|
)
|
||||||
|
self.worksheet.page_setup = setup
|
||||||
|
|
||||||
|
def set_margins(
|
||||||
|
self,
|
||||||
|
left: float = 0.7,
|
||||||
|
right: float = 0.7,
|
||||||
|
top: float = 0.75,
|
||||||
|
bottom: float = 0.75,
|
||||||
|
header: float = 0.3,
|
||||||
|
footer: float = 0.3
|
||||||
|
) -> None:
|
||||||
|
"""Set page margins in inches"""
|
||||||
|
margins = PageMargins(
|
||||||
|
left=left,
|
||||||
|
right=right,
|
||||||
|
top=top,
|
||||||
|
bottom=bottom,
|
||||||
|
header=header,
|
||||||
|
footer=footer
|
||||||
|
)
|
||||||
|
self.worksheet.page_margins = margins
|
||||||
|
|
||||||
|
def set_header_footer(
|
||||||
|
self,
|
||||||
|
odd_header: Optional[str] = None,
|
||||||
|
odd_footer: Optional[str] = None,
|
||||||
|
even_header: Optional[str] = None,
|
||||||
|
even_footer: Optional[str] = None,
|
||||||
|
first_header: Optional[str] = None,
|
||||||
|
first_footer: Optional[str] = None,
|
||||||
|
different_first: bool = False,
|
||||||
|
different_odd_even: bool = False
|
||||||
|
) -> None:
|
||||||
|
"""Set headers and footers
|
||||||
|
|
||||||
|
Format codes:
|
||||||
|
- &P: Page number
|
||||||
|
- &N: Total pages
|
||||||
|
- &D: Date
|
||||||
|
- &T: Time
|
||||||
|
- &[Tab]: Sheet name
|
||||||
|
- &[Path]: File path
|
||||||
|
- &[File]: File name
|
||||||
|
- &[Tab]: Worksheet name
|
||||||
|
"""
|
||||||
|
self.worksheet.oddHeader.left = odd_header or ""
|
||||||
|
self.worksheet.oddFooter.left = odd_footer or ""
|
||||||
|
|
||||||
|
if different_odd_even:
|
||||||
|
self.worksheet.evenHeader.left = even_header or ""
|
||||||
|
self.worksheet.evenFooter.left = even_footer or ""
|
||||||
|
|
||||||
|
if different_first:
|
||||||
|
self.worksheet.firstHeader.left = first_header or ""
|
||||||
|
self.worksheet.firstFooter.left = first_footer or ""
|
||||||
|
|
||||||
|
self.worksheet.differentFirst = different_first
|
||||||
|
self.worksheet.differentOddEven = different_odd_even
|
||||||
|
|
||||||
|
def set_print_area(self, range_string: str) -> None:
|
||||||
|
"""Set print area
|
||||||
|
|
||||||
|
Args:
|
||||||
|
range_string: Cell range in A1 notation (e.g., 'A1:H42')
|
||||||
|
"""
|
||||||
|
self.worksheet.print_area = range_string
|
||||||
|
|
||||||
|
def set_print_title_rows(self, rows: str) -> None:
|
||||||
|
"""Set rows to repeat at top of each page
|
||||||
|
|
||||||
|
Args:
|
||||||
|
rows: Row range (e.g., '1:3')
|
||||||
|
"""
|
||||||
|
self.worksheet.print_title_rows = rows
|
||||||
|
|
||||||
|
def set_print_title_columns(self, cols: str) -> None:
|
||||||
|
"""Set columns to repeat at left of each page
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cols: Column range (e.g., 'A:B')
|
||||||
|
"""
|
||||||
|
self.worksheet.print_title_cols = cols
|
||||||
|
|
||||||
|
def set_print_options(
|
||||||
|
self,
|
||||||
|
grid_lines: bool = False,
|
||||||
|
horizontal_centered: bool = False,
|
||||||
|
vertical_centered: bool = False,
|
||||||
|
headers: bool = False
|
||||||
|
) -> None:
|
||||||
|
"""Set print options"""
|
||||||
|
self.worksheet.print_gridlines = grid_lines
|
||||||
|
self.worksheet.print_options.horizontalCentered = horizontal_centered
|
||||||
|
self.worksheet.print_options.verticalCentered = vertical_centered
|
||||||
|
self.worksheet.print_options.headers = headers
|
||||||
|
|
||||||
|
class PaperSizes:
|
||||||
|
"""Standard paper size constants"""
|
||||||
|
LETTER = 1
|
||||||
|
LETTER_SMALL = 2
|
||||||
|
TABLOID = 3
|
||||||
|
LEDGER = 4
|
||||||
|
LEGAL = 5
|
||||||
|
STATEMENT = 6
|
||||||
|
EXECUTIVE = 7
|
||||||
|
A3 = 8
|
||||||
|
A4 = 9
|
||||||
|
A4_SMALL = 10
|
||||||
|
A5 = 11
|
||||||
|
B4 = 12
|
||||||
|
B5 = 13
|
||||||
115
SumasenLibs/excel_lib/sumaexcel/styles.py
Normal file
115
SumasenLibs/excel_lib/sumaexcel/styles.py
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
# sumaexcel/styles.py
|
||||||
|
from typing import Dict, Any, Optional, Union
|
||||||
|
from openpyxl.styles import (
|
||||||
|
Font, PatternFill, Alignment, Border, Side,
|
||||||
|
NamedStyle, Protection, Color
|
||||||
|
)
|
||||||
|
from openpyxl.styles.differential import DifferentialStyle
|
||||||
|
from openpyxl.formatting.rule import Rule
|
||||||
|
from openpyxl.worksheet.worksheet import Worksheet
|
||||||
|
|
||||||
|
class StyleManager:
|
||||||
|
"""Excel style management class"""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create_font(
|
||||||
|
name: str = "Arial",
|
||||||
|
size: int = 11,
|
||||||
|
bold: bool = False,
|
||||||
|
italic: bool = False,
|
||||||
|
color: str = "000000",
|
||||||
|
underline: str = None,
|
||||||
|
strike: bool = False
|
||||||
|
) -> Font:
|
||||||
|
"""Create a Font object with specified parameters"""
|
||||||
|
return Font(
|
||||||
|
name=name,
|
||||||
|
size=size,
|
||||||
|
bold=bold,
|
||||||
|
italic=italic,
|
||||||
|
color=color,
|
||||||
|
underline=underline,
|
||||||
|
strike=strike
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create_fill(
|
||||||
|
fill_type: str = "solid",
|
||||||
|
start_color: str = "FFFFFF",
|
||||||
|
end_color: str = None
|
||||||
|
) -> PatternFill:
|
||||||
|
"""Create a PatternFill object"""
|
||||||
|
return PatternFill(
|
||||||
|
fill_type=fill_type,
|
||||||
|
start_color=start_color,
|
||||||
|
end_color=end_color or start_color
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create_border(
|
||||||
|
style: str = "thin",
|
||||||
|
color: str = "000000"
|
||||||
|
) -> Border:
|
||||||
|
"""Create a Border object"""
|
||||||
|
side = Side(style=style, color=color)
|
||||||
|
return Border(
|
||||||
|
left=side,
|
||||||
|
right=side,
|
||||||
|
top=side,
|
||||||
|
bottom=side
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create_alignment(
|
||||||
|
horizontal: str = "general",
|
||||||
|
vertical: str = "bottom",
|
||||||
|
wrap_text: bool = False,
|
||||||
|
shrink_to_fit: bool = False,
|
||||||
|
indent: int = 0
|
||||||
|
) -> Alignment:
|
||||||
|
"""Create an Alignment object"""
|
||||||
|
return Alignment(
|
||||||
|
horizontal=horizontal,
|
||||||
|
vertical=vertical,
|
||||||
|
wrap_text=wrap_text,
|
||||||
|
shrink_to_fit=shrink_to_fit,
|
||||||
|
indent=indent
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def copy_style(source_cell: Any, target_cell: Any) -> None:
|
||||||
|
"""Copy all style properties from source cell to target cell"""
|
||||||
|
target_cell.font = Font(
|
||||||
|
name=source_cell.font.name,
|
||||||
|
size=source_cell.font.size,
|
||||||
|
bold=source_cell.font.bold,
|
||||||
|
italic=source_cell.font.italic,
|
||||||
|
color=source_cell.font.color,
|
||||||
|
underline=source_cell.font.underline,
|
||||||
|
strike=source_cell.font.strike
|
||||||
|
)
|
||||||
|
|
||||||
|
if source_cell.fill.patternType != None:
|
||||||
|
target_cell.fill = PatternFill(
|
||||||
|
fill_type=source_cell.fill.patternType,
|
||||||
|
start_color=source_cell.fill.start_color.rgb,
|
||||||
|
end_color=source_cell.fill.end_color.rgb
|
||||||
|
)
|
||||||
|
|
||||||
|
target_cell.border = Border(
|
||||||
|
left=source_cell.border.left,
|
||||||
|
right=source_cell.border.right,
|
||||||
|
top=source_cell.border.top,
|
||||||
|
bottom=source_cell.border.bottom
|
||||||
|
)
|
||||||
|
|
||||||
|
target_cell.alignment = Alignment(
|
||||||
|
horizontal=source_cell.alignment.horizontal,
|
||||||
|
vertical=source_cell.alignment.vertical,
|
||||||
|
wrap_text=source_cell.alignment.wrap_text,
|
||||||
|
shrink_to_fit=source_cell.alignment.shrink_to_fit,
|
||||||
|
indent=source_cell.alignment.indent
|
||||||
|
)
|
||||||
|
|
||||||
|
if source_cell.number_format:
|
||||||
|
target_cell.number_format = source_cell.number_format
|
||||||
276
SumasenLibs/excel_lib/sumaexcel/sumaexcel.py
Normal file
276
SumasenLibs/excel_lib/sumaexcel/sumaexcel.py
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
# sumaexcel/excel.py
|
||||||
|
|
||||||
|
import openpyxl
|
||||||
|
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
|
||||||
|
from openpyxl.utils import get_column_letter
|
||||||
|
import pandas as pd
|
||||||
|
from typing import Optional, Dict, List, Union, Any
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import Optional, Dict, Any, Union, Tuple
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from .styles import StyleManager
|
||||||
|
from .merge import MergeManager
|
||||||
|
from .image import ImageManager
|
||||||
|
from .conditional import ConditionalFormatManager
|
||||||
|
from .page import PageManager, PaperSizes
|
||||||
|
|
||||||
|
class SumasenExcel:
|
||||||
|
"""Enhanced Excel handling class with extended functionality"""
|
||||||
|
|
||||||
|
def __init__(self, debug: bool = False):
|
||||||
|
self.debug = debug
|
||||||
|
self.workbook = None
|
||||||
|
self.template_filepath = None
|
||||||
|
self.output_filepath = None
|
||||||
|
self.current_sheet = None
|
||||||
|
|
||||||
|
self._style_manager = None
|
||||||
|
self._merge_manager = None
|
||||||
|
self._image_manager = None
|
||||||
|
self._conditional_manager = None
|
||||||
|
self._page_manager = None
|
||||||
|
|
||||||
|
def init(self, username: str, project_id: str, document: str,
|
||||||
|
lang: str = "jp", docbase: str = "./docbase") -> Dict[str, str]:
|
||||||
|
"""Initialize Excel document with basic settings
|
||||||
|
|
||||||
|
Args:
|
||||||
|
username: User name for file operations
|
||||||
|
project_id: Project identifier
|
||||||
|
document: Document name
|
||||||
|
lang: Language code (default: "jp")
|
||||||
|
docbase: Base directory for documents (default: "./docbase")
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict with status ("ACK"/"NCK") and optional error message
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
self.username = username
|
||||||
|
self.project_id = project_id
|
||||||
|
self.language = lang
|
||||||
|
|
||||||
|
# Setup directory structure
|
||||||
|
self.docpath = docbase
|
||||||
|
self.docpath2 = f"{docbase}/{project_id}"
|
||||||
|
|
||||||
|
# Create directories if they don't exist
|
||||||
|
for path in [docbase, self.docpath2]:
|
||||||
|
if not os.path.exists(path):
|
||||||
|
os.makedirs(path, mode=0o755)
|
||||||
|
|
||||||
|
# Load template
|
||||||
|
inifile = f"{document}.ini"
|
||||||
|
self.inifilepath = f"{self.docpath2}/{inifile}"
|
||||||
|
|
||||||
|
if not os.path.exists(self.inifilepath):
|
||||||
|
return {"status": "NCK", "message": f"INI file not found: {self.inifilepath}"}
|
||||||
|
|
||||||
|
# Load template workbook
|
||||||
|
template_file = self._get_ini_param("basic", f"templatefile_{lang}")
|
||||||
|
self.template_filepath = f"{self.docpath2}/{template_file}"
|
||||||
|
|
||||||
|
if not os.path.exists(self.template_filepath):
|
||||||
|
# Copy from default if not exists
|
||||||
|
default_template = f"{self.docpath}/{template_file}"
|
||||||
|
shutil.copy2(default_template, self.template_filepath)
|
||||||
|
|
||||||
|
self.workbook = openpyxl.load_workbook(self.template_filepath)
|
||||||
|
|
||||||
|
return {"status": "ACK"}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return {"status": "NCK", "message": str(e)}
|
||||||
|
|
||||||
|
def _get_ini_param(self, section: str, param: str) -> Optional[str]:
|
||||||
|
"""Get parameter from INI file
|
||||||
|
|
||||||
|
Args:
|
||||||
|
section: INI file section
|
||||||
|
param: Parameter name
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Parameter value or None if not found
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Use configparser to handle INI files
|
||||||
|
import configparser
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read(self.inifilepath)
|
||||||
|
return config[section][param]
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def make_report(self, db, data_rec: Dict[str, Any],
|
||||||
|
out_filename: Optional[str] = None,
|
||||||
|
screen_index: int = 0) -> None:
|
||||||
|
"""Generate Excel report from template
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db: Database connection
|
||||||
|
data_rec: Data records to populate report
|
||||||
|
out_filename: Optional output filename
|
||||||
|
screen_index: Screen index for multi-screen reports
|
||||||
|
"""
|
||||||
|
# Get output filename
|
||||||
|
if out_filename:
|
||||||
|
outfile = f"{out_filename}_{self._get_ini_param('basic', 'doc_file')}"
|
||||||
|
else:
|
||||||
|
outfile = self._get_ini_param('basic', 'doc_file')
|
||||||
|
|
||||||
|
self.output_filepath = f"{self.docpath2}/{outfile}"
|
||||||
|
|
||||||
|
# Process sections
|
||||||
|
sections = self._get_ini_param('basic', 'sections')
|
||||||
|
if not sections:
|
||||||
|
return
|
||||||
|
|
||||||
|
for section in sections.split(','):
|
||||||
|
self._process_section(section, db, data_rec, screen_index)
|
||||||
|
|
||||||
|
# Save workbook
|
||||||
|
self.workbook.save(self.output_filepath)
|
||||||
|
|
||||||
|
def _process_section(self, section: str, db, data_rec: Dict[str, Any],
|
||||||
|
screen_index: int) -> None:
|
||||||
|
"""Process individual section of report
|
||||||
|
|
||||||
|
Args:
|
||||||
|
section: Section name
|
||||||
|
db: Database connection
|
||||||
|
data_rec: Data records
|
||||||
|
screen_index: Screen index
|
||||||
|
"""
|
||||||
|
# Get template sheet
|
||||||
|
sheet_orig = self._get_ini_param(section, 'sheet')
|
||||||
|
sheet_name = self._get_ini_param(section, f"sheetname_{self.language}")
|
||||||
|
|
||||||
|
if not sheet_orig or not sheet_name:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Copy template sheet
|
||||||
|
template_sheet = self.workbook[sheet_orig]
|
||||||
|
new_sheet = self.workbook.copy_worksheet(template_sheet)
|
||||||
|
new_sheet.title = sheet_name
|
||||||
|
|
||||||
|
# Process groups
|
||||||
|
groups = self._get_ini_param(section, 'groups')
|
||||||
|
if groups:
|
||||||
|
for group in groups.split(','):
|
||||||
|
self._process_group(new_sheet, section, group, db, data_rec, screen_index)
|
||||||
|
|
||||||
|
def _process_group(self, sheet, section: str, group: str,
|
||||||
|
db, data_rec: Dict[str, Any], screen_index: int) -> None:
|
||||||
|
"""Process group within section
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sheet: Worksheet to process
|
||||||
|
section: Section name
|
||||||
|
group: Group name
|
||||||
|
db: Database connection
|
||||||
|
data_rec: Data records
|
||||||
|
screen_index: Screen index
|
||||||
|
"""
|
||||||
|
pass # Implementation details will follow
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def init_sheet(self, sheet_name: str) -> None:
|
||||||
|
"""Initialize worksheet and managers"""
|
||||||
|
self.current_sheet = self.workbook[sheet_name]
|
||||||
|
self._style_manager = StyleManager()
|
||||||
|
self._merge_manager = MergeManager(self.current_sheet)
|
||||||
|
self._image_manager = ImageManager(self.current_sheet)
|
||||||
|
self._conditional_manager = ConditionalFormatManager(self.current_sheet)
|
||||||
|
self._page_manager = PageManager(self.current_sheet)
|
||||||
|
|
||||||
|
# Style operations
|
||||||
|
def apply_style(
|
||||||
|
self,
|
||||||
|
cell_range: str,
|
||||||
|
font: Dict[str, Any] = None,
|
||||||
|
fill: Dict[str, Any] = None,
|
||||||
|
border: Dict[str, Any] = None,
|
||||||
|
alignment: Dict[str, Any] = None
|
||||||
|
) -> None:
|
||||||
|
"""Apply styles to cell range"""
|
||||||
|
for row in self.current_sheet[cell_range]:
|
||||||
|
for cell in row:
|
||||||
|
if font:
|
||||||
|
cell.font = self._style_manager.create_font(**font)
|
||||||
|
if fill:
|
||||||
|
cell.fill = self._style_manager.create_fill(**fill)
|
||||||
|
if border:
|
||||||
|
cell.border = self._style_manager.create_border(**border)
|
||||||
|
if alignment:
|
||||||
|
cell.alignment = self._style_manager.create_alignment(**alignment)
|
||||||
|
|
||||||
|
# Merge operations
|
||||||
|
def merge_range(
|
||||||
|
self,
|
||||||
|
start_row: int,
|
||||||
|
start_col: int,
|
||||||
|
end_row: int,
|
||||||
|
end_col: int
|
||||||
|
) -> None:
|
||||||
|
"""Merge cell range"""
|
||||||
|
self._merge_manager.merge_cells(start_row, start_col, end_row, end_col)
|
||||||
|
|
||||||
|
# Image operations
|
||||||
|
def add_image(
|
||||||
|
self,
|
||||||
|
image_path: Union[str, Path],
|
||||||
|
position: Tuple[int, int],
|
||||||
|
size: Optional[Tuple[int, int]] = None
|
||||||
|
) -> None:
|
||||||
|
"""Add image to worksheet"""
|
||||||
|
self._image_manager.add_image(image_path, position, size)
|
||||||
|
|
||||||
|
# Conditional formatting
|
||||||
|
def add_conditional_format(
|
||||||
|
self,
|
||||||
|
cell_range: str,
|
||||||
|
format_type: str,
|
||||||
|
**kwargs
|
||||||
|
) -> None:
|
||||||
|
"""Add conditional formatting"""
|
||||||
|
if format_type == 'color_scale':
|
||||||
|
self._conditional_manager.add_color_scale(cell_range, **kwargs)
|
||||||
|
elif format_type == 'data_bar':
|
||||||
|
self._conditional_manager.add_data_bar(cell_range, **kwargs)
|
||||||
|
elif format_type == 'icon_set':
|
||||||
|
self._conditional_manager.add_icon_set(cell_range, **kwargs)
|
||||||
|
elif format_type == 'custom':
|
||||||
|
self._conditional_manager.add_custom_rule(cell_range, **kwargs)
|
||||||
|
|
||||||
|
# Page setup
|
||||||
|
def setup_page(
|
||||||
|
self,
|
||||||
|
orientation: str = 'portrait',
|
||||||
|
paper_size: int = PaperSizes.A4,
|
||||||
|
margins: Dict[str, float] = None,
|
||||||
|
header_footer: Dict[str, Any] = None
|
||||||
|
) -> None:
|
||||||
|
"""Configure page setup"""
|
||||||
|
self._page_manager.set_page_setup(
|
||||||
|
orientation=orientation,
|
||||||
|
paper_size=paper_size
|
||||||
|
)
|
||||||
|
|
||||||
|
if margins:
|
||||||
|
self._page_manager.set_margins(**margins)
|
||||||
|
|
||||||
|
if header_footer:
|
||||||
|
self._page_manager.set_header_footer(**header_footer)
|
||||||
|
|
||||||
|
def cleanup(self) -> None:
|
||||||
|
"""Cleanup temporary files"""
|
||||||
|
if self._image_manager:
|
||||||
|
self._image_manager.cleanup()
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
"""Destructor"""
|
||||||
|
self.cleanup()
|
||||||
55
SumasenLibs/excel_lib/testdata/sample.py
vendored
Normal file
55
SumasenLibs/excel_lib/testdata/sample.py
vendored
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
from sumaexcel import SumasenExcel
|
||||||
|
|
||||||
|
# 初期化
|
||||||
|
excel = SumasenExcel()
|
||||||
|
excel.init("username", "project_id", "document")
|
||||||
|
|
||||||
|
# シート初期化
|
||||||
|
excel.init_sheet("Sheet1")
|
||||||
|
|
||||||
|
# スタイル適用
|
||||||
|
excel.apply_style(
|
||||||
|
"A1:D10",
|
||||||
|
font={"name": "Arial", "size": 12, "bold": True},
|
||||||
|
fill={"start_color": "FFFF00"},
|
||||||
|
alignment={"horizontal": "center"}
|
||||||
|
)
|
||||||
|
|
||||||
|
# セルのマージ
|
||||||
|
excel.merge_range(1, 1, 1, 4)
|
||||||
|
|
||||||
|
# 画像追加
|
||||||
|
excel.add_image(
|
||||||
|
"logo.png",
|
||||||
|
position=(1, 1),
|
||||||
|
size=(100, 100)
|
||||||
|
)
|
||||||
|
|
||||||
|
# 条件付き書式
|
||||||
|
excel.add_conditional_format(
|
||||||
|
"B2:B10",
|
||||||
|
format_type="color_scale",
|
||||||
|
min_color="00FF0000",
|
||||||
|
max_color="0000FF00"
|
||||||
|
)
|
||||||
|
|
||||||
|
# ページ設定
|
||||||
|
excel.setup_page(
|
||||||
|
orientation="landscape",
|
||||||
|
paper_size=PaperSizes.A4,
|
||||||
|
margins={
|
||||||
|
"left": 1.0,
|
||||||
|
"right": 1.0,
|
||||||
|
"top": 1.0,
|
||||||
|
"bottom": 1.0
|
||||||
|
},
|
||||||
|
header_footer={
|
||||||
|
"odd_header": "&L&BPage &P of &N&C&BConfidential",
|
||||||
|
"odd_footer": "&RDraft"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# レポート生成
|
||||||
|
excel.make_report(db, data_rec)
|
||||||
|
|
||||||
|
|
||||||
25
SumasenLibs/excel_lib/testdata/test.ini
vendored
Normal file
25
SumasenLibs/excel_lib/testdata/test.ini
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
[basic]
|
||||||
|
templatefile_jp="certificate_template.xlsx"
|
||||||
|
doc_file="certificate_[zekken_number].xlsx"
|
||||||
|
sections=section1,section2
|
||||||
|
developer=Sumasen
|
||||||
|
maxcol=8
|
||||||
|
|
||||||
|
[section1]
|
||||||
|
sheet="certificate"
|
||||||
|
sheetname_jp="岐阜ロゲ通過証明書"
|
||||||
|
groups="group1,group2"
|
||||||
|
fit_to_width=1
|
||||||
|
orientation=portrait
|
||||||
|
|
||||||
|
[section1.group1]
|
||||||
|
table_name=rog_entry
|
||||||
|
where="zekken_number='[zekken_number]' and event_code='[event_code]'"
|
||||||
|
group_range="0,0,8,11"
|
||||||
|
|
||||||
|
[section1.group2]
|
||||||
|
table_name=gps_checkins
|
||||||
|
where=""zekken_number='[zekken_number]' and event_code='[event_code]'
|
||||||
|
sort=order
|
||||||
|
group_range=0,12,8,12
|
||||||
|
|
||||||
@ -53,10 +53,14 @@ INSTALLED_APPS = [
|
|||||||
'leaflet',
|
'leaflet',
|
||||||
'leaflet_admin_list',
|
'leaflet_admin_list',
|
||||||
'rog.apps.RogConfig',
|
'rog.apps.RogConfig',
|
||||||
|
'corsheaders', # added
|
||||||
'django_filters'
|
'django_filters'
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
'corsheaders.middleware.CorsMiddleware', # できるだけ上部に
|
||||||
|
'django.middleware.common.CommonMiddleware',
|
||||||
|
|
||||||
'django.middleware.security.SecurityMiddleware',
|
'django.middleware.security.SecurityMiddleware',
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
'django.middleware.common.CommonMiddleware',
|
'django.middleware.common.CommonMiddleware',
|
||||||
@ -68,10 +72,47 @@ MIDDLEWARE = [
|
|||||||
|
|
||||||
ROOT_URLCONF = 'config.urls'
|
ROOT_URLCONF = 'config.urls'
|
||||||
|
|
||||||
|
CORS_ALLOW_ALL_ORIGINS = True # 開発環境のみ
|
||||||
|
CORS_ALLOW_CREDENTIALS = True
|
||||||
|
|
||||||
|
CORS_ALLOWED_METHODS = [
|
||||||
|
'GET',
|
||||||
|
'POST',
|
||||||
|
'PUT',
|
||||||
|
'PATCH',
|
||||||
|
'DELETE',
|
||||||
|
'OPTIONS'
|
||||||
|
]
|
||||||
|
CORS_ALLOWED_HEADERS = [
|
||||||
|
'accept',
|
||||||
|
'accept-encoding',
|
||||||
|
'authorization',
|
||||||
|
'content-type',
|
||||||
|
'dnt',
|
||||||
|
'origin',
|
||||||
|
'user-agent',
|
||||||
|
'x-csrftoken',
|
||||||
|
'x-requested-with',
|
||||||
|
]
|
||||||
|
|
||||||
|
# 本番環境では以下のように制限する
|
||||||
|
CORS_ALLOWED_ORIGINS = [
|
||||||
|
"https://rogaining.sumasen.net",
|
||||||
|
"http://rogaining.sumasen.net",
|
||||||
|
]
|
||||||
|
|
||||||
|
# CSRFの設定
|
||||||
|
CSRF_TRUSTED_ORIGINS = [
|
||||||
|
"http://rogaining.sumasen.net",
|
||||||
|
"https://rogaining.sumasen.net",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
'DIRS': [BASE_DIR / 'templates'],
|
'DIRS': [os.path.join(BASE_DIR, 'templates')],
|
||||||
'APP_DIRS': True,
|
'APP_DIRS': True,
|
||||||
'OPTIONS': {
|
'OPTIONS': {
|
||||||
'context_processors': [
|
'context_processors': [
|
||||||
@ -138,10 +179,12 @@ USE_TZ = True
|
|||||||
STATIC_URL = '/static/'
|
STATIC_URL = '/static/'
|
||||||
|
|
||||||
#STATIC_URL = '/static2/'
|
#STATIC_URL = '/static2/'
|
||||||
STATIC_ROOT = BASE_DIR / "static"
|
#STATIC_ROOT = BASE_DIR / "static"
|
||||||
|
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
|
||||||
|
|
||||||
MEDIA_URL = '/media/'
|
MEDIA_URL = '/media/'
|
||||||
MEDIA_ROOT = BASE_DIR / "media/"
|
#MEDIA_ROOT = BASE_DIR / "media/"
|
||||||
|
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
|
||||||
|
|
||||||
#STATICFILES_DIRS = (os.path.join(BASE_DIR, "static2"),os.path.join(BASE_DIR, "media"))
|
#STATICFILES_DIRS = (os.path.join(BASE_DIR, "static2"),os.path.join(BASE_DIR, "media"))
|
||||||
|
|
||||||
@ -173,4 +216,88 @@ LEAFLET_CONFIG = {
|
|||||||
REST_FRAMEWORK = {
|
REST_FRAMEWORK = {
|
||||||
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
|
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
|
||||||
'DEFAULT_AUTHENTICATION_CLASSES': ('knox.auth.TokenAuthentication', ),
|
'DEFAULT_AUTHENTICATION_CLASSES': ('knox.auth.TokenAuthentication', ),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#FRONTEND_URL = 'https://rogaining.intranet.sumasen.net' # フロントエンドのURLに適宜変更してください
|
||||||
|
FRONTEND_URL = 'https://rogaining.sumasen.net' # フロントエンドのURLに適宜変更してください
|
||||||
|
|
||||||
|
# この設定により、メールは実際には送信されず、代わりにコンソールに出力されます。
|
||||||
|
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||||
|
|
||||||
|
EMAIL_HOST = 'smtp.outlook.com'
|
||||||
|
EMAIL_PORT = 587
|
||||||
|
EMAIL_USE_TLS = True
|
||||||
|
EMAIL_HOST_USER = 'rogaining@gifuai.net'
|
||||||
|
EMAIL_HOST_PASSWORD = 'ctcpy9823"x~'
|
||||||
|
DEFAULT_FROM_EMAIL = 'rogaining@gifuai.net'
|
||||||
|
|
||||||
|
APP_DOWNLOAD_LINK = 'https://apps.apple.com/jp/app/%E5%B2%90%E9%98%9C%E3%83%8A%E3%83%93/id6444221792'
|
||||||
|
ANDROID_DOWNLOAD_LINK = 'https://play.google.com/store/apps/details?id=com.dvox.gifunavi&hl=ja'
|
||||||
|
|
||||||
|
SERVICE_NAME = '岐阜ナビ(岐阜ロゲのアプリ)'
|
||||||
|
|
||||||
|
# settings.py
|
||||||
|
DEFAULT_CHARSET = 'utf-8'
|
||||||
|
|
||||||
|
#REST_FRAMEWORK = {
|
||||||
|
# 'DEFAULT_RENDERER_CLASSES': [
|
||||||
|
# 'rest_framework.renderers.JSONRenderer',
|
||||||
|
# ],
|
||||||
|
# 'JSON_UNICODE_ESCAPE': False,
|
||||||
|
#}
|
||||||
|
|
||||||
|
LOGGING = {
|
||||||
|
'version': 1,
|
||||||
|
'disable_existing_loggers': False,
|
||||||
|
'formatters': {
|
||||||
|
'verbose': {
|
||||||
|
'format': '{levelname} {asctime} {module} {message}',
|
||||||
|
'style': '{',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'handlers': {
|
||||||
|
#'file': {
|
||||||
|
# 'level': 'DEBUG',
|
||||||
|
# 'class': 'logging.FileHandler',
|
||||||
|
# 'filename': os.path.join(BASE_DIR, 'logs/debug.log'),
|
||||||
|
# 'formatter': 'verbose',
|
||||||
|
#},
|
||||||
|
'console': {
|
||||||
|
'level': 'DEBUG',
|
||||||
|
'class': 'logging.StreamHandler',
|
||||||
|
'formatter': 'verbose',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'root': {
|
||||||
|
'handlers': ['console'],
|
||||||
|
'level': 'DEBUG',
|
||||||
|
},
|
||||||
|
'loggers': {
|
||||||
|
'django': {
|
||||||
|
'handlers': ['console'],
|
||||||
|
'level': 'INFO',
|
||||||
|
'propagate': False,
|
||||||
|
},
|
||||||
|
'django.request': {
|
||||||
|
'handlers': ['console'],
|
||||||
|
'level': 'DEBUG',
|
||||||
|
},
|
||||||
|
'rog': {
|
||||||
|
#'handlers': ['file','console'],
|
||||||
|
'handlers': ['console'],
|
||||||
|
'level': 'DEBUG',
|
||||||
|
'propagate': True,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
PASSWORD_HASHERS = [
|
||||||
|
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
|
||||||
|
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
|
||||||
|
'django.contrib.auth.hashers.Argon2PasswordHasher',
|
||||||
|
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
|
||||||
|
]
|
||||||
|
|
||||||
|
BLACKLISTED_IPS = ['44.230.58.114'] # ブロックしたい IP アドレスをここにリストとして追加
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,21 @@ from django.urls import path, include
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.conf.urls.static import static
|
from django.conf.urls.static import static
|
||||||
|
|
||||||
|
|
||||||
|
# debug_urlsビューをrogアプリケーションのviewsからインポート
|
||||||
|
from rog import views as rog_views
|
||||||
|
|
||||||
|
DEBUG = True
|
||||||
|
ALLOWED_HOSTS = ['rogaining.sumasen.net', 'localhost', '127.0.0.1']
|
||||||
|
|
||||||
|
# CORSの設定
|
||||||
|
CORS_ALLOW_ALL_ORIGINS = True
|
||||||
|
CORS_ALLOWED_ORIGINS = [
|
||||||
|
"http://rogaining.sumasen.net",
|
||||||
|
"http://localhost",
|
||||||
|
"http://127.0.0.1",
|
||||||
|
]
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
path('auth/', include('knox.urls')),
|
path('auth/', include('knox.urls')),
|
||||||
@ -27,3 +42,8 @@ urlpatterns = [
|
|||||||
admin.site.site_header = "ROGANING"
|
admin.site.site_header = "ROGANING"
|
||||||
admin.site.site_title = "Roganing Admin Portal"
|
admin.site.site_title = "Roganing Admin Portal"
|
||||||
admin.site.index_title = "Welcome to Roganing Portal"
|
admin.site.index_title = "Welcome to Roganing Portal"
|
||||||
|
|
||||||
|
# 開発環境での静的ファイル配信
|
||||||
|
if settings.DEBUG:
|
||||||
|
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||||
|
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
|||||||
@ -30,12 +30,41 @@ services:
|
|||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
restart: "on-failure"
|
restart: "on-failure"
|
||||||
# depends_on:
|
|
||||||
# - postgres-db
|
|
||||||
networks:
|
networks:
|
||||||
- rog-api
|
- rog-api
|
||||||
#entrypoint: ["/app/wait-for.sh", "postgres-db:5432", "--", ""]
|
|
||||||
#command: python3 manage.py runserver 0.0.0.0:8100
|
supervisor-web:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.supervisor
|
||||||
|
volumes:
|
||||||
|
- type: bind
|
||||||
|
source: ./supervisor/html
|
||||||
|
target: /usr/share/nginx/html/supervisor
|
||||||
|
read_only: true
|
||||||
|
- type: bind
|
||||||
|
source: ./supervisor/nginx/default.conf
|
||||||
|
target: /etc/nginx/conf.d/default.conf
|
||||||
|
read_only: true
|
||||||
|
- type: volume
|
||||||
|
source: static_volume
|
||||||
|
target: /app/static
|
||||||
|
read_only: true
|
||||||
|
- type: volume
|
||||||
|
source: nginx_logs
|
||||||
|
target: /var/log/nginx
|
||||||
|
- type: bind
|
||||||
|
source: ./media
|
||||||
|
target: /usr/share/nginx/html/media
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
networks:
|
||||||
|
- rog-api
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
rog-api:
|
rog-api:
|
||||||
@ -44,3 +73,5 @@ networks:
|
|||||||
volumes:
|
volumes:
|
||||||
postgres_data:
|
postgres_data:
|
||||||
geoserver-data:
|
geoserver-data:
|
||||||
|
static_volume:
|
||||||
|
nginx_logs:
|
||||||
|
|||||||
81
docker-compose.yaml.ssl
Normal file
81
docker-compose.yaml.ssl
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
version: "3.9"
|
||||||
|
|
||||||
|
services:
|
||||||
|
# postgres-db:
|
||||||
|
# image: kartoza/postgis:12.0
|
||||||
|
# ports:
|
||||||
|
# - 5432:5432
|
||||||
|
# volumes:
|
||||||
|
# - postgres_data:/var/lib/postgresql
|
||||||
|
# - ./custom-postgresql.conf:/etc/postgresql/12/main/postgresql.conf
|
||||||
|
# environment:
|
||||||
|
# - POSTGRES_USER=${POSTGRES_USER}
|
||||||
|
# - POSTGRES_PASS=${POSTGRES_PASS}
|
||||||
|
# - POSTGRES_DBNAME=${POSTGRES_DBNAME}
|
||||||
|
# - POSTGRES_MAX_CONNECTIONS=600
|
||||||
|
|
||||||
|
# restart: "on-failure"
|
||||||
|
# networks:
|
||||||
|
# - rog-api
|
||||||
|
|
||||||
|
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
|
||||||
|
#entrypoint: ["/app/wait-for.sh", "postgres-db:5432", "--", ""]
|
||||||
|
#command: python3 manage.py runserver 0.0.0.0:8100
|
||||||
|
|
||||||
|
supervisor-web:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.supervisor
|
||||||
|
volumes:
|
||||||
|
- type: bind
|
||||||
|
source: /etc/letsencrypt
|
||||||
|
target: /etc/nginx/ssl
|
||||||
|
read_only: true
|
||||||
|
- type: bind
|
||||||
|
source: ./supervisor/html
|
||||||
|
target: /usr/share/nginx/html
|
||||||
|
read_only: true
|
||||||
|
- type: bind
|
||||||
|
source: ./supervisor/nginx/default.conf
|
||||||
|
target: /etc/nginx/conf.d/default.conf
|
||||||
|
read_only: true
|
||||||
|
- type: volume
|
||||||
|
source: static_volume
|
||||||
|
target: /app/static
|
||||||
|
read_only: true
|
||||||
|
- type: volume
|
||||||
|
source: nginx_logs
|
||||||
|
target: /var/log/nginx
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
networks:
|
||||||
|
- rog-api
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
|
||||||
|
networks:
|
||||||
|
rog-api:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
|
geoserver-data:
|
||||||
|
static_volume:
|
||||||
|
nginx_logs:
|
||||||
1
dump_rog_data.sql
Normal file
1
dump_rog_data.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
pg_dump: error: connection to database "rogdb" failed: FATAL: Peer authentication failed for user "postgres"
|
||||||
10
entrypoint.sh
Normal file
10
entrypoint.sh
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Collect static files
|
||||||
|
python manage.py collectstatic --noinput
|
||||||
|
|
||||||
|
# Apply database migrations
|
||||||
|
python manage.py migrate
|
||||||
|
|
||||||
|
# Start Gunicorn
|
||||||
|
exec "$@"
|
||||||
32
nginx.conf
32
nginx.conf
@ -26,29 +26,33 @@ http {
|
|||||||
#gzip on;
|
#gzip on;
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
server_name localhost;
|
server_name localhost;
|
||||||
|
|
||||||
|
# 静的ファイルの提供
|
||||||
location /static/ {
|
location /static/ {
|
||||||
alias /app/static/;
|
alias /app/static/;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /media/ {
|
# スーパーバイザー Web アプリケーション
|
||||||
alias /app/media/;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://app:8000;
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Django API プロキシ
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://api:8000;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_page 500 502 503 504 /50x.html;
|
error_page 500 502 503 504 /50x.html;
|
||||||
location = /50x.html {
|
location = /50x.html {
|
||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,3 +65,4 @@ django-extra-fields==3.0.2
|
|||||||
django-phonenumber-field==6.1.0
|
django-phonenumber-field==6.1.0
|
||||||
django-rest-knox==4.2.0
|
django-rest-knox==4.2.0
|
||||||
dj-database-url==2.0.0
|
dj-database-url==2.0.0
|
||||||
|
django-cors-headers==4.3.0
|
||||||
|
|||||||
1203
rog/admin.py
1203
rog/admin.py
File diff suppressed because it is too large
Load Diff
@ -3,12 +3,18 @@ from django.conf import settings
|
|||||||
from .models import CustomUser
|
from .models import CustomUser
|
||||||
from django.contrib.auth.backends import ModelBackend
|
from django.contrib.auth.backends import ModelBackend
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
from django.contrib.auth.hashers import check_password
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class EmailOrUsernameModelBackend(ModelBackend):
|
class EmailOrUsernameModelBackend(ModelBackend):
|
||||||
"""
|
"""
|
||||||
This is a ModelBacked that allows authentication
|
This is a ModelBacked that allows authentication
|
||||||
with either a username or an email address.
|
with either a username or an email address.
|
||||||
|
|
||||||
|
"""
|
||||||
"""
|
"""
|
||||||
def authenticate(self, username=None, password=None):
|
def authenticate(self, username=None, password=None):
|
||||||
if '@' in username:
|
if '@' in username:
|
||||||
@ -26,4 +32,35 @@ class EmailOrUsernameModelBackend(ModelBackend):
|
|||||||
try:
|
try:
|
||||||
return CustomUser.objects.get(pk=username)
|
return CustomUser.objects.get(pk=username)
|
||||||
except get_user_model().DoesNotExist:
|
except get_user_model().DoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
"""
|
||||||
|
|
||||||
|
def authenticate(self, request, username=None, password=None, **kwargs):
|
||||||
|
if '@' in username:
|
||||||
|
kwargs = {'email': username}
|
||||||
|
else:
|
||||||
|
kwargs = {'username': username}
|
||||||
|
try:
|
||||||
|
user = CustomUser.objects.get(**kwargs)
|
||||||
|
if check_password(password, user.password):
|
||||||
|
logger.info(f"User authenticated successfully: {username}")
|
||||||
|
return user
|
||||||
|
else:
|
||||||
|
logger.warning(f"Password mismatch for user: {username}")
|
||||||
|
except CustomUser.DoesNotExist:
|
||||||
|
logger.warning(f"User does not exist: {username}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Authentication error for {username}: {str(e)}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_user(self, user_id):
|
||||||
|
try:
|
||||||
|
user = CustomUser.objects.get(pk=user_id)
|
||||||
|
logger.info(f"User retrieved: {user.username or user.email}")
|
||||||
|
return user
|
||||||
|
except CustomUser.DoesNotExist:
|
||||||
|
logger.warning(f"User with id {user_id} does not exist")
|
||||||
|
return None
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error retrieving user with id {user_id}: {str(e)}")
|
||||||
|
return None
|
||||||
|
|||||||
7
rog/forms.py
Normal file
7
rog/forms.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from django import forms
|
||||||
|
from .models import NewEvent2
|
||||||
|
|
||||||
|
class CSVUploadForm(forms.Form):
|
||||||
|
event = forms.ModelChoiceField(queryset=NewEvent2.objects.all(), label="イベント選択")
|
||||||
|
csv_file = forms.FileField(label="CSVファイル")
|
||||||
|
|
||||||
40
rog/gifuroge_team.csv
Normal file
40
rog/gifuroge_team.csv
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
4019,関ケ原2,Best Wishes,ソロ女子-5時間,pbkdf2_sha256$260000$RPvncicp11ENXxwpcpMXi1$9e/fKcfwaX3sJ91q9S70KWQcrNlraliguiHjF/UCW/I=
|
||||||
|
4010,関ケ原2,まつげん,ソロ女子-5時間,pbkdf2_sha256$260000$LMvH0KtHeHbCuuUZ5n88VZ$Lnsqs/u45QKoFN6lUdqC79nIMz5LwaKWMpmX/0aEXa8=
|
||||||
|
4021,大垣3,まつげん,ソロ女子-5時間,pbkdf2_sha256$260000$LMvH0KtHeHbCuuUZ5n88VZ$Lnsqs/u45QKoFN6lUdqC79nIMz5LwaKWMpmX/0aEXa8=
|
||||||
|
5,関ケ原2,てすとあきら1,ソロ男子-5時間,pbkdf2_sha256$260000$0GY5pt5V127jGd8HkkEort$8ZL0eY2qTZHydyzUUN5LNKZnmmibfu1x3QQ/7rJX1Vc=
|
||||||
|
3003,関ケ原2,てすとあきら1,ソロ男子-5時間,pbkdf2_sha256$260000$0GY5pt5V127jGd8HkkEort$8ZL0eY2qTZHydyzUUN5LNKZnmmibfu1x3QQ/7rJX1Vc=
|
||||||
|
3115,関ケ原2,Best Wishes,ソロ男子-5時間,pbkdf2_sha256$260000$tlNrgHyqDtfbM9f3GLv5G1$jRcR/ieTB174TZ9jW7obCBUMpyz86aywqDKw3VmhVQQ=
|
||||||
|
1010,大垣3,ハヤノテスト,一般-5時間,pbkdf2_sha256$260000$IeGmRkkUkwXXc1zO9oxvCe$ijnJTH7xhwidit+uCggSgjj/7g/vMK539IpOMA5GlnM=
|
||||||
|
1012,大垣3,てすとあきら1,一般-5時間,pbkdf2_sha256$260000$0GY5pt5V127jGd8HkkEort$8ZL0eY2qTZHydyzUUN5LNKZnmmibfu1x3QQ/7rJX1Vc=
|
||||||
|
1014,各務原2,てすとあきら1,一般-5時間,pbkdf2_sha256$260000$0GY5pt5V127jGd8HkkEort$8ZL0eY2qTZHydyzUUN5LNKZnmmibfu1x3QQ/7rJX1Vc=
|
||||||
|
1018,下呂2,てすとあきら1,一般-5時間,pbkdf2_sha256$260000$0GY5pt5V127jGd8HkkEort$8ZL0eY2qTZHydyzUUN5LNKZnmmibfu1x3QQ/7rJX1Vc=
|
||||||
|
1024,関ケ原2,てすとあきら1,一般-5時間,pbkdf2_sha256$260000$0GY5pt5V127jGd8HkkEort$8ZL0eY2qTZHydyzUUN5LNKZnmmibfu1x3QQ/7rJX1Vc=
|
||||||
|
1026,美濃加茂2,てすとあきら1,一般-5時間,pbkdf2_sha256$260000$0GY5pt5V127jGd8HkkEort$8ZL0eY2qTZHydyzUUN5LNKZnmmibfu1x3QQ/7rJX1Vc=
|
||||||
|
1028,多治見2,てすとあきら1,一般-5時間,pbkdf2_sha256$260000$0GY5pt5V127jGd8HkkEort$8ZL0eY2qTZHydyzUUN5LNKZnmmibfu1x3QQ/7rJX1Vc=
|
||||||
|
3006,関ケ原2,山本哲也,ソロ男子-5時間,pbkdf2_sha256$260000$EkYrRHZwKunjO4jiHvxyB2$kYGN0STzV9c70IKAIxK1Ija3K1y90+ote0HDTP+iSPw=
|
||||||
|
3009,養老2,山本哲也,ソロ男子-5時間,pbkdf2_sha256$260000$EkYrRHZwKunjO4jiHvxyB2$kYGN0STzV9c70IKAIxK1Ija3K1y90+ote0HDTP+iSPw=
|
||||||
|
3011,郡上2,山本哲也,ソロ男子-5時間,pbkdf2_sha256$260000$EkYrRHZwKunjO4jiHvxyB2$kYGN0STzV9c70IKAIxK1Ija3K1y90+ote0HDTP+iSPw=
|
||||||
|
3013,大垣3,山本哲也,ソロ男子-5時間,pbkdf2_sha256$260000$EkYrRHZwKunjO4jiHvxyB2$kYGN0STzV9c70IKAIxK1Ija3K1y90+ote0HDTP+iSPw=
|
||||||
|
3015,各務原2,山本哲也,ソロ男子-5時間,pbkdf2_sha256$260000$EkYrRHZwKunjO4jiHvxyB2$kYGN0STzV9c70IKAIxK1Ija3K1y90+ote0HDTP+iSPw=
|
||||||
|
3017,多治見2,山本哲也,ソロ男子-5時間,pbkdf2_sha256$260000$EkYrRHZwKunjO4jiHvxyB2$kYGN0STzV9c70IKAIxK1Ija3K1y90+ote0HDTP+iSPw=
|
||||||
|
3019,下呂2,山本哲也,ソロ男子-5時間,pbkdf2_sha256$260000$EkYrRHZwKunjO4jiHvxyB2$kYGN0STzV9c70IKAIxK1Ija3K1y90+ote0HDTP+iSPw=
|
||||||
|
3021,高山2,山本哲也,ソロ男子-5時間,pbkdf2_sha256$260000$EkYrRHZwKunjO4jiHvxyB2$kYGN0STzV9c70IKAIxK1Ija3K1y90+ote0HDTP+iSPw=
|
||||||
|
3023,美濃加茂2,山本哲也,ソロ男子-5時間,pbkdf2_sha256$260000$EkYrRHZwKunjO4jiHvxyB2$kYGN0STzV9c70IKAIxK1Ija3K1y90+ote0HDTP+iSPw=
|
||||||
|
4008,下呂2,GO!GO!YOKO,ソロ女子-5時間,pbkdf2_sha256$260000$tuv8ajw2VSmCooIxNHJhdD$m7q0fqPIsAs7L9uubt+PUVsmexwpJPXPCgVs9GjY12c=
|
||||||
|
3121,関ケ原2,yamadeus,ソロ男子-5時間,pbkdf2_sha256$260000$sCLRTCAxQIClyDmvfbMDm0$cU3dSGTPwKHl8T3EBZ6R19oZJGkadD48pKqywAhtJOk=
|
||||||
|
3126,大垣3,yamadeus,ソロ男子-5時間,pbkdf2_sha256$260000$7KsSngw2Ho719jpXsOrC8v$jfHFxglG/L0htA13t01LAy91dS+FnlAZubg6Lmd/m2Y=
|
||||||
|
3128,多治見2,MASA,ソロ男子-5時間,pbkdf2_sha256$260000$qpaSbqryD4f5bZaY893Ug4$Gk8XuqsJbSkX9Hxrl/xg9LtjM8JQkpgNkpbbNzTmhzY=
|
||||||
|
3124,関ケ原2,yamadeus,ソロ男子-5時間,pbkdf2_sha256$260000$7KsSngw2Ho719jpXsOrC8v$jfHFxglG/L0htA13t01LAy91dS+FnlAZubg6Lmd/m2Y=
|
||||||
|
3132,各務原2,岐阜市イイとこあるある探検隊,ソロ男子-5時間,pbkdf2_sha256$260000$QWc5BpSBUbkUwP9UlIzyE5$do+VKkH8mNibg6PJDsm6AJ/VMFh3NWdzwZ9IQW/26xA=
|
||||||
|
3135,大垣3,akira,ソロ男子-5時間,pbkdf2_sha256$260000$mmM2N8sSE84YaNNuDzQKxb$ox9U6rdgZq4ANzi4NizskphZWIrf7o2+JEfvC4wcn7U=
|
||||||
|
3137,関ケ原2,akira,ソロ男子-5時間,pbkdf2_sha256$260000$mmM2N8sSE84YaNNuDzQKxb$ox9U6rdgZq4ANzi4NizskphZWIrf7o2+JEfvC4wcn7U=
|
||||||
|
3139,養老2,akira,ソロ男子-5時間,pbkdf2_sha256$260000$mmM2N8sSE84YaNNuDzQKxb$ox9U6rdgZq4ANzi4NizskphZWIrf7o2+JEfvC4wcn7U=
|
||||||
|
3073,養老2,yamadeus,ソロ男子-5時間,pbkdf2_sha256$260000$sCLRTCAxQIClyDmvfbMDm0$cU3dSGTPwKHl8T3EBZ6R19oZJGkadD48pKqywAhtJOk=
|
||||||
|
3075,高山2,yamadeus,ソロ男子-5時間,pbkdf2_sha256$260000$sCLRTCAxQIClyDmvfbMDm0$cU3dSGTPwKHl8T3EBZ6R19oZJGkadD48pKqywAhtJOk=
|
||||||
|
3077,郡上2,yamadeus,ソロ男子-5時間,pbkdf2_sha256$260000$sCLRTCAxQIClyDmvfbMDm0$cU3dSGTPwKHl8T3EBZ6R19oZJGkadD48pKqywAhtJOk=
|
||||||
|
3081,美濃加茂2,yamadeus,ソロ男子-5時間,pbkdf2_sha256$260000$sCLRTCAxQIClyDmvfbMDm0$cU3dSGTPwKHl8T3EBZ6R19oZJGkadD48pKqywAhtJOk=
|
||||||
|
3083,多治見2,yamadeus,ソロ男子-5時間,pbkdf2_sha256$260000$sCLRTCAxQIClyDmvfbMDm0$cU3dSGTPwKHl8T3EBZ6R19oZJGkadD48pKqywAhtJOk=
|
||||||
|
3085,各務原2,yamadeus,ソロ男子-5時間,pbkdf2_sha256$260000$sCLRTCAxQIClyDmvfbMDm0$cU3dSGTPwKHl8T3EBZ6R19oZJGkadD48pKqywAhtJOk=
|
||||||
|
3079,下呂2,yamadeus,ソロ男子-5時間,pbkdf2_sha256$260000$sCLRTCAxQIClyDmvfbMDm0$cU3dSGTPwKHl8T3EBZ6R19oZJGkadD48pKqywAhtJOk=
|
||||||
|
3093,関ケ原2,岐阜愛,ソロ男子-5時間,pbkdf2_sha256$260000$LFOINdd30aKaXoT9CNYY8A$eoAzV10+gp+tufabtcFOx6uoOktZUngzzDJ0WWs/v24=
|
||||||
|
3099,高山2,岐阜愛,ソロ男子-5時間,pbkdf2_sha256$260000$LFOINdd30aKaXoT9CNYY8A$eoAzV10+gp+tufabtcFOx6uoOktZUngzzDJ0WWs/v24=
|
||||||
|
3
rog/middleware/__init__.py
Normal file
3
rog/middleware/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from .ip_blocking import IPBlockingMiddleware
|
||||||
|
|
||||||
|
__all__ = ['IPBlockingMiddleware']
|
||||||
42
rog/middleware/ip_blocking.py
Normal file
42
rog/middleware/ip_blocking.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
from django.core.exceptions import PermissionDenied
|
||||||
|
from django.core.cache import cache
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
class IPBlockingMiddleware:
|
||||||
|
def __init__(self, get_response):
|
||||||
|
self.get_response = get_response
|
||||||
|
# 事前にブロックする IP アドレスのリスト
|
||||||
|
self.blacklisted_ips = getattr(settings, 'BLACKLISTED_IPS', [])
|
||||||
|
|
||||||
|
def __call__(self, request):
|
||||||
|
ip = self.get_client_ip(request)
|
||||||
|
|
||||||
|
# キャッシュからブロックリストを取得
|
||||||
|
blocked_ips = cache.get('blocked_ips', set())
|
||||||
|
|
||||||
|
# 事前にブロックされた IP またはキャッシュ内のブロックされた IP をチェック
|
||||||
|
if ip in self.blacklisted_ips or ip in blocked_ips:
|
||||||
|
raise PermissionDenied
|
||||||
|
|
||||||
|
# 不正アクセスの検出ロジックをここに実装
|
||||||
|
if self.is_suspicious(ip):
|
||||||
|
blocked_ips.add(ip)
|
||||||
|
cache.set('blocked_ips', blocked_ips, timeout=3600) # 1時間ブロック
|
||||||
|
raise PermissionDenied
|
||||||
|
|
||||||
|
response = self.get_response(request)
|
||||||
|
return response
|
||||||
|
|
||||||
|
def is_suspicious(self, ip):
|
||||||
|
request_count = cache.get(f'request_count_{ip}', 0)
|
||||||
|
cache.set(f'request_count_{ip}', request_count + 1, timeout=60)
|
||||||
|
return request_count > 100 # 1分間に100回以上のリクエストがあれば不審と判断
|
||||||
|
|
||||||
|
def get_client_ip(self, request):
|
||||||
|
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
|
||||||
|
if x_forwarded_for:
|
||||||
|
ip = x_forwarded_for.split(',')[0]
|
||||||
|
else:
|
||||||
|
ip = request.META.get('REMOTE_ADDR')
|
||||||
|
return ip
|
||||||
|
|
||||||
148
rog/migration_scripts.py
Normal file
148
rog/migration_scripts.py
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
"""
|
||||||
|
このコードは永栄コードをNoufferコードに統合するための一時変換コードです。
|
||||||
|
一旦、完全にマイグレーションでき、ランキングや走行履歴が完成したら、不要になります。
|
||||||
|
"""
|
||||||
|
import psycopg2
|
||||||
|
from PIL import Image
|
||||||
|
import PIL.ExifTags
|
||||||
|
from datetime import datetime
|
||||||
|
import os
|
||||||
|
|
||||||
|
def get_gps_from_image(image_path):
|
||||||
|
"""
|
||||||
|
画像ファイルからGPS情報を抽出する
|
||||||
|
Returns: (latitude, longitude) または取得できない場合は (None, None)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with Image.open(image_path) as img:
|
||||||
|
exif = {
|
||||||
|
PIL.ExifTags.TAGS[k]: v
|
||||||
|
for k, v in img._getexif().items()
|
||||||
|
if k in PIL.ExifTags.TAGS
|
||||||
|
}
|
||||||
|
|
||||||
|
if 'GPSInfo' in exif:
|
||||||
|
gps_info = exif['GPSInfo']
|
||||||
|
|
||||||
|
# 緯度の計算
|
||||||
|
lat = gps_info[2]
|
||||||
|
lat = lat[0] + lat[1]/60 + lat[2]/3600
|
||||||
|
if gps_info[1] == 'S':
|
||||||
|
lat = -lat
|
||||||
|
|
||||||
|
# 経度の計算
|
||||||
|
lon = gps_info[4]
|
||||||
|
lon = lon[0] + lon[1]/60 + lon[2]/3600
|
||||||
|
if gps_info[3] == 'W':
|
||||||
|
lon = -lon
|
||||||
|
|
||||||
|
return lat, lon
|
||||||
|
except Exception as e:
|
||||||
|
print(f"GPS情報の抽出に失敗: {e}")
|
||||||
|
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
def migrate_data():
|
||||||
|
# コンテナ環境用の接続情報
|
||||||
|
source_db = {
|
||||||
|
'dbname': 'gifuroge',
|
||||||
|
'user': 'admin', # 環境に合わせて変更
|
||||||
|
'password': 'admin123456', # 環境に合わせて変更
|
||||||
|
'host': 'localhost', # Dockerのサービス名
|
||||||
|
'port': '5432'
|
||||||
|
}
|
||||||
|
|
||||||
|
target_db = {
|
||||||
|
'dbname': 'rogdb',
|
||||||
|
'user': 'admin', # 環境に合わせて変更
|
||||||
|
'password': 'admin123456', # 環境に合わせて変更
|
||||||
|
'host': 'localhost', # Dockerのサービス名
|
||||||
|
'port': '5432'
|
||||||
|
}
|
||||||
|
|
||||||
|
source_conn = None
|
||||||
|
target_conn = None
|
||||||
|
source_cur = None
|
||||||
|
target_cur = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
print("ソースDBへの接続を試みています...")
|
||||||
|
source_conn = psycopg2.connect(**source_db)
|
||||||
|
source_cur = source_conn.cursor()
|
||||||
|
print("ソースDBへの接続が成功しました")
|
||||||
|
|
||||||
|
print("ターゲットDBへの接続を試みています...")
|
||||||
|
target_conn = psycopg2.connect(**target_db)
|
||||||
|
target_cur = target_conn.cursor()
|
||||||
|
print("ターゲットDBへの接続が成功しました")
|
||||||
|
|
||||||
|
print("データの取得を開始します...")
|
||||||
|
source_cur.execute("""
|
||||||
|
SELECT serial_number, zekken_number, event_code, cp_number, image_address,
|
||||||
|
goal_time, late_point, create_at, create_user,
|
||||||
|
update_at, update_user, buy_flag, colabo_company_memo
|
||||||
|
FROM gps_information
|
||||||
|
""")
|
||||||
|
|
||||||
|
rows = source_cur.fetchall()
|
||||||
|
print(f"取得したレコード数: {len(rows)}")
|
||||||
|
|
||||||
|
processed_count = 0
|
||||||
|
for row in rows:
|
||||||
|
(serial_number, zekken_number, event_code, cp_number, image_address,
|
||||||
|
goal_time, late_point, create_at, create_user,
|
||||||
|
update_at, update_user, buy_flag, colabo_company_memo) = row
|
||||||
|
|
||||||
|
latitude, longitude = None, None
|
||||||
|
if image_address and os.path.exists(image_address):
|
||||||
|
latitude, longitude = get_gps_from_image(image_address)
|
||||||
|
|
||||||
|
target_cur.execute("""
|
||||||
|
INSERT INTO gps_checkins (
|
||||||
|
path_order, zekken_number, event_code, cp_number,
|
||||||
|
lattitude, longitude, image_address,
|
||||||
|
image_receipt, image_QR, validate_location,
|
||||||
|
goal_time, late_point, create_at,
|
||||||
|
create_user, update_at, update_user,
|
||||||
|
buy_flag, colabo_company_memo, points
|
||||||
|
) VALUES (
|
||||||
|
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
|
||||||
|
%s, %s, %s, %s, %s, %s, %s, %s, %s
|
||||||
|
)
|
||||||
|
""", (
|
||||||
|
serial_number,
|
||||||
|
zekken_number, event_code, cp_number,
|
||||||
|
latitude, longitude, image_address,
|
||||||
|
True, True, True,
|
||||||
|
goal_time, late_point, create_at,
|
||||||
|
create_user, update_at, update_user,
|
||||||
|
buy_flag if buy_flag is not None else False,
|
||||||
|
colabo_company_memo if colabo_company_memo else '',
|
||||||
|
0
|
||||||
|
))
|
||||||
|
|
||||||
|
processed_count += 1
|
||||||
|
if processed_count % 100 == 0:
|
||||||
|
print(f"処理済みレコード数: {processed_count}")
|
||||||
|
|
||||||
|
target_conn.commit()
|
||||||
|
print(f"移行完了: {processed_count}件のレコードを処理しました")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"エラーが発生しました: {e}")
|
||||||
|
if target_conn:
|
||||||
|
target_conn.rollback()
|
||||||
|
|
||||||
|
finally:
|
||||||
|
if source_cur:
|
||||||
|
source_cur.close()
|
||||||
|
if target_cur:
|
||||||
|
target_cur.close()
|
||||||
|
if source_conn:
|
||||||
|
source_conn.close()
|
||||||
|
if target_conn:
|
||||||
|
target_conn.close()
|
||||||
|
print("すべての接続をクローズしました")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
migrate_data()
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
351
rog/migrations_backup/0001_initial.py
Normal file
351
rog/migrations_backup/0001_initial.py
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-05-04 15:05
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
import django.contrib.gis.db.models.fields
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import rog.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('auth', '0012_alter_user_first_name_max_length'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='JpnAdminMainPerf',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)),
|
||||||
|
('adm0_en', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm0_ja', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm0_pcode', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm1_en', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm1_ja', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm1_pcode', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'jpn_admin_main_perf',
|
||||||
|
'managed': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='JpnAdminPerf',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('geom', django.contrib.gis.db.models.fields.MultiLineStringField(blank=True, null=True, srid=4326)),
|
||||||
|
('et_id', models.IntegerField(blank=True, null=True)),
|
||||||
|
('et_right', models.CharField(blank=True, max_length=80, null=True)),
|
||||||
|
('et_left', models.CharField(blank=True, max_length=80, null=True)),
|
||||||
|
('adm2_l', models.CharField(blank=True, max_length=50, null=True)),
|
||||||
|
('adm1_l', models.CharField(blank=True, max_length=50, null=True)),
|
||||||
|
('adm0_l', models.CharField(blank=True, max_length=50, null=True)),
|
||||||
|
('adm0_r', models.CharField(blank=True, max_length=50, null=True)),
|
||||||
|
('adm1_r', models.CharField(blank=True, max_length=50, null=True)),
|
||||||
|
('adm2_r', models.CharField(blank=True, max_length=50, null=True)),
|
||||||
|
('admlevel', models.IntegerField(blank=True, null=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'jpn_admin_perf',
|
||||||
|
'managed': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='JpnSubPerf',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)),
|
||||||
|
('adm0_en', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm0_ja', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm0_pcode', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm1_en', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm1_ja', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm1_pcode', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm2_ja', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm2_en', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm2_pcode', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'jpn_sub_perf',
|
||||||
|
'managed': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='CustomUser',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('password', models.CharField(max_length=128, verbose_name='password')),
|
||||||
|
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
||||||
|
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
||||||
|
('email', models.EmailField(max_length=254, unique=True, verbose_name='email address')),
|
||||||
|
('is_staff', models.BooleanField(default=False)),
|
||||||
|
('is_active', models.BooleanField(default=False)),
|
||||||
|
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
|
||||||
|
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Location',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('location_id', models.IntegerField(blank=True, null=True, verbose_name='Location id')),
|
||||||
|
('location_name', models.CharField(default='--- 場所をお願いします --', max_length=255, verbose_name='Location Name')),
|
||||||
|
('category', models.CharField(blank=True, max_length=255, null=True, verbose_name='Category')),
|
||||||
|
('zip', models.CharField(blank=True, max_length=12, null=True, verbose_name='Zip code')),
|
||||||
|
('address', models.CharField(blank=True, max_length=512, null=True, verbose_name='Address')),
|
||||||
|
('prefecture', models.CharField(blank=True, max_length=255, null=True, verbose_name='Prefecture')),
|
||||||
|
('area', models.CharField(blank=True, max_length=255, null=True, verbose_name='Area')),
|
||||||
|
('city', models.CharField(blank=True, max_length=255, null=True, verbose_name='City')),
|
||||||
|
('latitude', models.FloatField(blank=True, null=True, verbose_name='Latitude')),
|
||||||
|
('longitude', models.FloatField(blank=True, null=True, verbose_name='Latitude')),
|
||||||
|
('photos', models.CharField(blank=True, max_length=255, null=True, verbose_name='Phptos')),
|
||||||
|
('videos', models.CharField(blank=True, max_length=255, null=True, verbose_name='Videos')),
|
||||||
|
('webcontents', models.CharField(blank=True, max_length=255, null=True, verbose_name='Web Content')),
|
||||||
|
('status', models.CharField(blank=True, max_length=255, null=True, verbose_name='Status')),
|
||||||
|
('portal', models.CharField(blank=True, max_length=255, null=True, verbose_name='Portal')),
|
||||||
|
('group', models.CharField(blank=True, max_length=255, null=True, verbose_name='Group')),
|
||||||
|
('phone', models.CharField(blank=True, max_length=255, null=True, verbose_name='Phone')),
|
||||||
|
('fax', models.CharField(blank=True, max_length=255, null=True, verbose_name='Fax')),
|
||||||
|
('email', models.EmailField(blank=True, max_length=255, null=True, verbose_name='Email')),
|
||||||
|
('facility', models.CharField(blank=True, max_length=255, null=True, verbose_name='Facility')),
|
||||||
|
('remark', models.CharField(blank=True, max_length=255, null=True, verbose_name='Remarks')),
|
||||||
|
('tags', models.CharField(blank=True, max_length=512, null=True, verbose_name='Tags')),
|
||||||
|
('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('last_updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('geom', django.contrib.gis.db.models.fields.MultiPointField(srid=4326)),
|
||||||
|
('last_updated_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='location_updated_user', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='ShapeLayers',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=255, verbose_name='Shape Layer')),
|
||||||
|
('file', models.FileField(blank=True, upload_to=rog.models.get_file_path)),
|
||||||
|
('uploaded_date', models.DateField(auto_now_add=True)),
|
||||||
|
('layerof', models.IntegerField(choices=[(1, 'location'), (2, 'Location_line'), (3, 'Location_polygon')], default=1)),
|
||||||
|
('table_name', models.CharField(blank=True, max_length=255, verbose_name='Table name')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='TestModel',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('testbane', models.CharField(max_length=355, verbose_name='test field')),
|
||||||
|
('wanttogo', models.BooleanField(default=False)),
|
||||||
|
('like', models.BooleanField(default=False)),
|
||||||
|
('checkin', models.BooleanField(default=False)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('last_updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='TravelList',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('travel_id', models.IntegerField(verbose_name='Travel Id')),
|
||||||
|
('start_date', models.DateTimeField(blank=True, null=True, verbose_name='Start date')),
|
||||||
|
('finish_date', models.DateTimeField(blank=True, null=True, verbose_name='End date')),
|
||||||
|
('category', models.CharField(choices=[('PRIVATE', 'Private'), ('GROUP', 'Group'), ('AGENT', 'Agent'), ('ROGAINING', 'Rogaining')], max_length=256)),
|
||||||
|
('title', models.CharField(max_length=255, verbose_name='Title')),
|
||||||
|
('transportation', models.CharField(blank=True, max_length=255, null=True, verbose_name='Transpotation')),
|
||||||
|
('moving_distance', models.IntegerField(blank=True, null=True)),
|
||||||
|
('duration', models.DurationField(blank=True, null=True, verbose_name='Duration')),
|
||||||
|
('eta', models.DateTimeField(blank=True, null=True)),
|
||||||
|
('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('last_updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='travel_list_updated_user', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Useractions',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('wanttogo', models.BooleanField(default=False)),
|
||||||
|
('like', models.BooleanField(default=False)),
|
||||||
|
('checkin', models.BooleanField(default=False)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('last_updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='action_location', to='rog.location')),
|
||||||
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='action_user', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='TravelPoint',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('distance', models.FloatField(blank=True, null=True)),
|
||||||
|
('transportation', models.CharField(blank=True, max_length=255, null=True, verbose_name='Transpotation')),
|
||||||
|
('eta', models.DateTimeField(blank=True, null=True)),
|
||||||
|
('order_number', models.IntegerField(blank=True, null=True)),
|
||||||
|
('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('last_updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='travelpoint_updated_user', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.location')),
|
||||||
|
('travel_list', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='rog.travellist')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SystemSettings',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('setting_name', models.CharField(max_length=255, verbose_name='Settings Name')),
|
||||||
|
('version', models.CharField(blank=True, max_length=10, null=True, verbose_name='Version')),
|
||||||
|
('effective_date', models.DateTimeField()),
|
||||||
|
('end_date', models.DateTimeField()),
|
||||||
|
('parammeters', models.CharField(max_length=512, verbose_name='Parameters')),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('last_updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='system_setting_updated_user', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='RogUser',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('email', models.EmailField(max_length=254, verbose_name='Email')),
|
||||||
|
('phone', models.CharField(max_length=55, verbose_name='Phone Number')),
|
||||||
|
('first_name', models.CharField(max_length=255, verbose_name='First Name')),
|
||||||
|
('middle_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='Middle Name')),
|
||||||
|
('last_name', models.CharField(max_length=255, verbose_name='last_name')),
|
||||||
|
('nickname', models.CharField(blank=True, max_length=255, null=True, verbose_name='Nickname')),
|
||||||
|
('country', models.CharField(default='Japan', max_length=255, verbose_name='Country')),
|
||||||
|
('language', models.CharField(default='Japanese', max_length=255, verbose_name='Language')),
|
||||||
|
('prefecture', models.CharField(blank=True, max_length=255, null=True, verbose_name='Prefecture')),
|
||||||
|
('sex', models.CharField(blank=True, default='unknown', max_length=255, null=True, verbose_name='Sex')),
|
||||||
|
('birthyear', models.IntegerField(blank=True, null=True, verbose_name='Birth year')),
|
||||||
|
('family_structure', models.IntegerField(blank=True, null=True, verbose_name='Family Structure')),
|
||||||
|
('level', models.IntegerField(blank=True, default=0, null=True, verbose_name='Level')),
|
||||||
|
('parammeters', models.CharField(max_length=512, verbose_name='Parameters')),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('last_updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('introducer', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='introduced_uesr', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='roguser_updated_user', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Location_polygon',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('location_id', models.IntegerField(blank=True, null=True, verbose_name='Location id')),
|
||||||
|
('location_name', models.CharField(max_length=255, verbose_name='Location Name')),
|
||||||
|
('category', models.CharField(blank=True, max_length=255, null=True, verbose_name='Category')),
|
||||||
|
('zip', models.CharField(blank=True, max_length=12, null=True, verbose_name='Zip code')),
|
||||||
|
('address', models.CharField(blank=True, max_length=512, null=True, verbose_name='Address')),
|
||||||
|
('prefecture', models.CharField(blank=True, max_length=255, null=True, verbose_name='Prefecture')),
|
||||||
|
('area', models.CharField(blank=True, max_length=255, null=True, verbose_name='Area')),
|
||||||
|
('city', models.CharField(blank=True, max_length=255, null=True, verbose_name='City')),
|
||||||
|
('photos', models.CharField(blank=True, max_length=255, null=True, verbose_name='Phptos')),
|
||||||
|
('videos', models.CharField(blank=True, max_length=255, null=True, verbose_name='Videos')),
|
||||||
|
('webcontents', models.CharField(blank=True, max_length=255, null=True, verbose_name='Web Content')),
|
||||||
|
('status', models.CharField(blank=True, max_length=255, null=True, verbose_name='Status')),
|
||||||
|
('portal', models.CharField(blank=True, max_length=255, null=True, verbose_name='Portal')),
|
||||||
|
('group', models.CharField(blank=True, max_length=255, null=True, verbose_name='Group')),
|
||||||
|
('phone', models.CharField(blank=True, max_length=255, null=True, verbose_name='Phone')),
|
||||||
|
('fax', models.CharField(blank=True, max_length=255, null=True, verbose_name='Fax')),
|
||||||
|
('email', models.EmailField(blank=True, max_length=255, null=True, verbose_name='Email')),
|
||||||
|
('facility', models.CharField(blank=True, max_length=255, null=True, verbose_name='Facility')),
|
||||||
|
('remark', models.CharField(blank=True, max_length=255, null=True, verbose_name='Remarks')),
|
||||||
|
('tags', models.CharField(blank=True, max_length=512, null=True, verbose_name='Tags')),
|
||||||
|
('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('last_updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)),
|
||||||
|
('last_updated_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='location_polygon_updated_user', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Location_line',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('location_id', models.IntegerField(blank=True, null=True, verbose_name='Location id')),
|
||||||
|
('location_name', models.CharField(max_length=255, verbose_name='Location Name')),
|
||||||
|
('category', models.CharField(blank=True, max_length=255, null=True, verbose_name='Category')),
|
||||||
|
('zip', models.CharField(blank=True, max_length=12, null=True, verbose_name='Zip code')),
|
||||||
|
('address', models.CharField(blank=True, max_length=512, null=True, verbose_name='Address')),
|
||||||
|
('prefecture', models.CharField(blank=True, max_length=255, null=True, verbose_name='Prefecture')),
|
||||||
|
('area', models.CharField(blank=True, max_length=255, null=True, verbose_name='Area')),
|
||||||
|
('city', models.CharField(blank=True, max_length=255, null=True, verbose_name='City')),
|
||||||
|
('photos', models.CharField(blank=True, max_length=255, null=True, verbose_name='Phptos')),
|
||||||
|
('videos', models.CharField(blank=True, max_length=255, null=True, verbose_name='Videos')),
|
||||||
|
('webcontents', models.CharField(blank=True, max_length=255, null=True, verbose_name='Web Content')),
|
||||||
|
('status', models.CharField(blank=True, max_length=255, null=True, verbose_name='Status')),
|
||||||
|
('portal', models.CharField(blank=True, max_length=255, null=True, verbose_name='Portal')),
|
||||||
|
('group', models.CharField(blank=True, max_length=255, null=True, verbose_name='Group')),
|
||||||
|
('phone', models.CharField(blank=True, max_length=255, null=True, verbose_name='Phone')),
|
||||||
|
('fax', models.CharField(blank=True, max_length=255, null=True, verbose_name='Fax')),
|
||||||
|
('email', models.EmailField(blank=True, max_length=255, null=True, verbose_name='Email')),
|
||||||
|
('facility', models.CharField(blank=True, max_length=255, null=True, verbose_name='Facility')),
|
||||||
|
('remark', models.CharField(blank=True, max_length=255, null=True, verbose_name='Remarks')),
|
||||||
|
('tags', models.CharField(blank=True, max_length=512, null=True, verbose_name='Tags')),
|
||||||
|
('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('last_updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('geom', django.contrib.gis.db.models.fields.MultiLineStringField(blank=True, null=True, srid=4326)),
|
||||||
|
('last_updated_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='location_line_updated_user', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='JoinedEvent',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('tagname', models.CharField(blank=True, max_length=255, null=True, verbose_name='Tag Name')),
|
||||||
|
('status', models.CharField(choices=[('REGISTERED', 'Registered'), ('ACCEPTED', 'accepted'), ('PAID', 'paid'), ('JOINED', 'joined'), ('CANCELED', 'Canceled')], max_length=256)),
|
||||||
|
('registrationid', models.CharField(max_length=56, verbose_name='Registration Id')),
|
||||||
|
('payment_code', models.CharField(max_length=255, verbose_name='Payment Code')),
|
||||||
|
('paid', models.IntegerField(default=0, verbose_name='Paid Amount')),
|
||||||
|
('remark', models.CharField(blank=True, max_length=255, null=True, verbose_name='Remark')),
|
||||||
|
('parammeters', models.CharField(max_length=512, verbose_name='Parameters')),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('last_updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='joined_event_updated_user', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Favorite',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('good', models.IntegerField(default=0, verbose_name='Good')),
|
||||||
|
('favorite', models.IntegerField(default=0, verbose_name='Favorite')),
|
||||||
|
('evaluation', models.IntegerField(default=0, verbose_name='Evaluation')),
|
||||||
|
('number_visit', models.IntegerField(default=0, verbose_name='Good')),
|
||||||
|
('last_visited', models.DateTimeField(blank=True, null=True, verbose_name='Last Visited')),
|
||||||
|
('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('last_updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('last_updated_user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='favorite_updated_user', to=settings.AUTH_USER_MODEL)),
|
||||||
|
('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.location')),
|
||||||
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Event',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('tagname', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')),
|
||||||
|
('status', models.CharField(choices=[('PREPARING', 'Preparing'), ('PROMOTION', 'Promotion'), ('EVENT', 'Event'), ('END', 'End')], max_length=256)),
|
||||||
|
('price', models.IntegerField(default=0, verbose_name='Paid Amount')),
|
||||||
|
('promotion_date', models.DateTimeField(blank=True, null=True, verbose_name='Promotion date')),
|
||||||
|
('event_start', models.DateTimeField(blank=True, null=True, verbose_name='Promotion date')),
|
||||||
|
('event_end', models.DateTimeField(blank=True, null=True, verbose_name='Promotion date')),
|
||||||
|
('remark', models.CharField(blank=True, max_length=256, null=True)),
|
||||||
|
('parammeters', models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters')),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('last_updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('last_updated_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='event_updated_user', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
23
rog/migrations_backup/0002_auto_20220511_2017.py
Normal file
23
rog/migrations_backup/0002_auto_20220511_2017.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-05-11 11:17
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='useractions',
|
||||||
|
name='order',
|
||||||
|
field=models.IntegerField(default=-1),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='customuser',
|
||||||
|
name='is_active',
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
rog/migrations_backup/0003_alter_useractions_order.py
Normal file
18
rog/migrations_backup/0003_alter_useractions_order.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-05-11 17:52
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0002_auto_20220511_2017'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='useractions',
|
||||||
|
name='order',
|
||||||
|
field=models.IntegerField(default=0),
|
||||||
|
),
|
||||||
|
]
|
||||||
55
rog/migrations_backup/0004_auto_20220606_0023.py
Normal file
55
rog/migrations_backup/0004_auto_20220606_0023.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-06-05 15:23
|
||||||
|
|
||||||
|
import django.contrib.gis.db.models.fields
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0003_alter_useractions_order'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='GifuAreas',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('geom', django.contrib.gis.db.models.fields.MultiPolygonField(blank=True, null=True, srid=4326)),
|
||||||
|
('adm0_en', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm0_ja', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm0_pcode', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm1_en', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm1_ja', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm1_pcode', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm2_ja', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm2_en', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('adm2_pcode', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
('area_nm', models.CharField(blank=True, max_length=254, null=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'gifu_areas',
|
||||||
|
'managed': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='auto_checkin',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='Is Autologin'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='checkin_radious',
|
||||||
|
field=models.IntegerField(blank=True, null=True, verbose_name='Checkin Radious'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='event_active',
|
||||||
|
field=models.BooleanField(default=True, verbose_name='Is Autologin'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='event_name',
|
||||||
|
field=models.CharField(blank=True, max_length=512, null=True, verbose_name='Tags'),
|
||||||
|
),
|
||||||
|
]
|
||||||
23
rog/migrations_backup/0005_auto_20220606_1523.py
Normal file
23
rog/migrations_backup/0005_auto_20220606_1523.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-06-06 06:23
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0004_auto_20220606_0023'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='event_active',
|
||||||
|
field=models.BooleanField(default=True, verbose_name='Is Event active'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='event_name',
|
||||||
|
field=models.CharField(blank=True, max_length=512, null=True, verbose_name='Event name'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
rog/migrations_backup/0006_location_paid.py
Normal file
18
rog/migrations_backup/0006_location_paid.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-06-07 13:00
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0005_auto_20220606_1523'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='paid',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='Is Paid'),
|
||||||
|
),
|
||||||
|
]
|
||||||
22
rog/migrations_backup/0007_auto_20220607_2207.py
Normal file
22
rog/migrations_backup/0007_auto_20220607_2207.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-06-07 13:07
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0006_location_paid'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='location',
|
||||||
|
name='paid',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='roguser',
|
||||||
|
name='paid',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='Is Paid'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
rog/migrations_backup/0008_alter_roguser_parammeters.py
Normal file
18
rog/migrations_backup/0008_alter_roguser_parammeters.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-06-07 13:09
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0007_auto_20220607_2207'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='roguser',
|
||||||
|
name='parammeters',
|
||||||
|
field=models.CharField(blank=True, max_length=512, null=True, verbose_name='Parameters'),
|
||||||
|
),
|
||||||
|
]
|
||||||
17
rog/migrations_backup/0009_remove_roguser_email.py
Normal file
17
rog/migrations_backup/0009_remove_roguser_email.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-06-07 14:24
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0008_alter_roguser_parammeters'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='roguser',
|
||||||
|
name='email',
|
||||||
|
),
|
||||||
|
]
|
||||||
18
rog/migrations_backup/0010_useractions_checkinimage.py
Normal file
18
rog/migrations_backup/0010_useractions_checkinimage.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-06-10 06:25
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0009_remove_roguser_email'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='useractions',
|
||||||
|
name='checkinimage',
|
||||||
|
field=models.FileField(blank=True, null=True, upload_to='%y%m%d'),
|
||||||
|
),
|
||||||
|
]
|
||||||
25
rog/migrations_backup/0011_usertracks.py
Normal file
25
rog/migrations_backup/0011_usertracks.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-06-12 18:11
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
import django.contrib.gis.db.models.fields
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0010_useractions_checkinimage'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='UserTracks',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('geom', django.contrib.gis.db.models.fields.MultiPointField(srid=4326)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
113
rog/migrations_backup/0012_auto_20220613_1758.py
Normal file
113
rog/migrations_backup/0012_auto_20220613_1758.py
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-06-13 08:58
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0011_usertracks'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='address',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Address'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='area',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Area'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='category',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Category'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='city',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='City'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='email',
|
||||||
|
field=models.EmailField(blank=True, max_length=2048, null=True, verbose_name='Email'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='event_name',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Event name'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='facility',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Facility'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='fax',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Fax'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='group',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Group'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='location_name',
|
||||||
|
field=models.CharField(default='--- 場所をお願いします --', max_length=2048, verbose_name='Location Name'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='parammeters',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Parameters'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='phone',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Phone'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='photos',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Phptos'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='portal',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Portal'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='prefecture',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Prefecture'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='remark',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Remarks'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='status',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Status'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='tags',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Tags'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='videos',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Videos'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='webcontents',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Web Content'),
|
||||||
|
),
|
||||||
|
]
|
||||||
88
rog/migrations_backup/0013_auto_20220618_1847.py
Normal file
88
rog/migrations_backup/0013_auto_20220618_1847.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-06-18 09:47
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0012_auto_20220613_1758'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='buy_point',
|
||||||
|
field=models.IntegerField(blank=True, default=0, null=True, verbose_name='buy Point'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='checkin_point',
|
||||||
|
field=models.IntegerField(blank=True, default=10, null=True, verbose_name='Checkin Point'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='checkin_radius',
|
||||||
|
field=models.IntegerField(blank=True, default=15, null=True, verbose_name='Checkin radious'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='evaluation_value',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Evaluation value (評価)'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='hidden_location',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='Is Hidden Location'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='opening_hours_fri',
|
||||||
|
field=models.TimeField(blank=True, null=True, verbose_name='Opening hours frinday (金曜)'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='opening_hours_mon',
|
||||||
|
field=models.TimeField(blank=True, null=True, verbose_name='Opening hours monday (月曜)'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='opening_hours_sat',
|
||||||
|
field=models.TimeField(blank=True, null=True, verbose_name='Opening hours saturday (土曜)'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='opening_hours_sun',
|
||||||
|
field=models.TimeField(blank=True, null=True, verbose_name='Opening hours sunday (日曜)'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='opening_hours_thu',
|
||||||
|
field=models.TimeField(blank=True, null=True, verbose_name='Opening hours thursday (木曜)'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='opening_hours_tue',
|
||||||
|
field=models.TimeField(blank=True, null=True, verbose_name='Opening hours tuesday (火曜)'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='opening_hours_wed',
|
||||||
|
field=models.TimeField(blank=True, null=True, verbose_name='Opening hours wednesday (水曜)'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='shop_closed',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='Shop Closed (休業)'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='shop_shutdown',
|
||||||
|
field=models.BooleanField(default=False, null=True, verbose_name='Shop Shutdown (閉業)'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='auto_checkin',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='Is AutoCheckin'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
rog/migrations_backup/0014_alter_location_shop_shutdown.py
Normal file
18
rog/migrations_backup/0014_alter_location_shop_shutdown.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-06-18 09:52
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0013_auto_20220618_1847'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='shop_shutdown',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='Shop Shutdown (閉業)'),
|
||||||
|
),
|
||||||
|
]
|
||||||
57
rog/migrations_backup/0015_auto_20220619_1611.py
Normal file
57
rog/migrations_backup/0015_auto_20220619_1611.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-06-19 07:11
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0014_alter_location_shop_shutdown'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='location',
|
||||||
|
name='checkin_radious',
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='opening_hours_fri',
|
||||||
|
field=models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours frinday (金曜)'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='opening_hours_mon',
|
||||||
|
field=models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours monday (月曜)'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='opening_hours_sat',
|
||||||
|
field=models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours saturday (土曜)'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='opening_hours_sun',
|
||||||
|
field=models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours sunday (日曜)'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='opening_hours_thu',
|
||||||
|
field=models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours thursday (木曜)'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='opening_hours_tue',
|
||||||
|
field=models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours tuesday (火曜)'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='opening_hours_wed',
|
||||||
|
field=models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours wednesday (水曜)'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='photos',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Photos'),
|
||||||
|
),
|
||||||
|
]
|
||||||
21
rog/migrations_backup/0016_shapefilelocations.py
Normal file
21
rog/migrations_backup/0016_shapefilelocations.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-06-21 09:46
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0015_auto_20220619_1611'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='ShapeFileLocations',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('shapefile', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Shapelayer')),
|
||||||
|
('locid', models.IntegerField(blank=True, null=True)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
23
rog/migrations_backup/0017_auto_20220725_1605.py
Normal file
23
rog/migrations_backup/0017_auto_20220725_1605.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-07-25 07:05
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0016_shapefilelocations'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='cp',
|
||||||
|
field=models.IntegerField(blank=True, null=True, verbose_name='Check Point'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='subcategory',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Sub Category'),
|
||||||
|
),
|
||||||
|
]
|
||||||
23
rog/migrations_backup/0018_auto_20220816_1616.py
Normal file
23
rog/migrations_backup/0018_auto_20220816_1616.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-08-16 07:16
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0017_auto_20220725_1605'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='location',
|
||||||
|
name='sub_loc_id',
|
||||||
|
field=models.IntegerField(blank=True, null=True, verbose_name='Sub location id'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='cp',
|
||||||
|
field=models.FloatField(blank=True, null=True, verbose_name='Check Point'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
rog/migrations_backup/0019_alter_location_checkin_radius.py
Normal file
18
rog/migrations_backup/0019_alter_location_checkin_radius.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-08-16 07:25
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0018_auto_20220816_1616'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='checkin_radius',
|
||||||
|
field=models.FloatField(blank=True, default=15.0, null=True, verbose_name='Checkin radious'),
|
||||||
|
),
|
||||||
|
]
|
||||||
23
rog/migrations_backup/0020_auto_20220816_1627.py
Normal file
23
rog/migrations_backup/0020_auto_20220816_1627.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-08-16 07:27
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0019_alter_location_checkin_radius'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='buy_point',
|
||||||
|
field=models.FloatField(blank=True, default=0, null=True, verbose_name='buy Point'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='checkin_point',
|
||||||
|
field=models.FloatField(blank=True, default=10, null=True, verbose_name='Checkin Point'),
|
||||||
|
),
|
||||||
|
]
|
||||||
69
rog/migrations_backup/0021_templocation.py
Normal file
69
rog/migrations_backup/0021_templocation.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-08-17 05:48
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
import django.contrib.gis.db.models.fields
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0020_auto_20220816_1627'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='templocation',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('location_id', models.IntegerField(blank=True, null=True, verbose_name='Location id')),
|
||||||
|
('sub_loc_id', models.IntegerField(blank=True, null=True, verbose_name='Sub location id')),
|
||||||
|
('cp', models.FloatField(blank=True, null=True, verbose_name='Check Point')),
|
||||||
|
('location_name', models.CharField(default='--- 場所をお願いします --', max_length=2048, verbose_name='Location Name')),
|
||||||
|
('category', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Category')),
|
||||||
|
('subcategory', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Sub Category')),
|
||||||
|
('zip', models.CharField(blank=True, max_length=12, null=True, verbose_name='Zip code')),
|
||||||
|
('address', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Address')),
|
||||||
|
('prefecture', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Prefecture')),
|
||||||
|
('area', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Area')),
|
||||||
|
('city', models.CharField(blank=True, max_length=2048, null=True, verbose_name='City')),
|
||||||
|
('latitude', models.FloatField(blank=True, null=True, verbose_name='Latitude')),
|
||||||
|
('longitude', models.FloatField(blank=True, null=True, verbose_name='Latitude')),
|
||||||
|
('photos', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Photos')),
|
||||||
|
('videos', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Videos')),
|
||||||
|
('webcontents', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Web Content')),
|
||||||
|
('status', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Status')),
|
||||||
|
('portal', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Portal')),
|
||||||
|
('group', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Group')),
|
||||||
|
('phone', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Phone')),
|
||||||
|
('fax', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Fax')),
|
||||||
|
('email', models.EmailField(blank=True, max_length=2048, null=True, verbose_name='Email')),
|
||||||
|
('facility', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Facility')),
|
||||||
|
('remark', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Remarks')),
|
||||||
|
('tags', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Tags')),
|
||||||
|
('event_name', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Event name')),
|
||||||
|
('event_active', models.BooleanField(default=True, verbose_name='Is Event active')),
|
||||||
|
('hidden_location', models.BooleanField(default=False, verbose_name='Is Hidden Location')),
|
||||||
|
('auto_checkin', models.BooleanField(default=False, verbose_name='Is AutoCheckin')),
|
||||||
|
('checkin_radius', models.FloatField(blank=True, default=15.0, null=True, verbose_name='Checkin radious')),
|
||||||
|
('checkin_point', models.FloatField(blank=True, default=10, null=True, verbose_name='Checkin Point')),
|
||||||
|
('buy_point', models.FloatField(blank=True, default=0, null=True, verbose_name='buy Point')),
|
||||||
|
('evaluation_value', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Evaluation value (評価)')),
|
||||||
|
('shop_closed', models.BooleanField(default=False, verbose_name='Shop Closed (休業)')),
|
||||||
|
('shop_shutdown', models.BooleanField(default=False, verbose_name='Shop Shutdown (閉業)')),
|
||||||
|
('opening_hours_mon', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours monday (月曜)')),
|
||||||
|
('opening_hours_tue', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours tuesday (火曜)')),
|
||||||
|
('opening_hours_wed', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours wednesday (水曜)')),
|
||||||
|
('opening_hours_thu', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours thursday (木曜)')),
|
||||||
|
('opening_hours_fri', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours frinday (金曜)')),
|
||||||
|
('opening_hours_sat', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours saturday (土曜)')),
|
||||||
|
('opening_hours_sun', models.CharField(blank=True, max_length=512, null=True, verbose_name='Opening hours sunday (日曜)')),
|
||||||
|
('parammeters', models.CharField(blank=True, max_length=2048, null=True, verbose_name='Parameters')),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('last_updated_at', models.DateTimeField(auto_now=True)),
|
||||||
|
('geom', django.contrib.gis.db.models.fields.MultiPointField(srid=4326)),
|
||||||
|
('last_updated_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='temp_location_updated_user', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
23
rog/migrations_backup/0022_auto_20220822_2319.py
Normal file
23
rog/migrations_backup/0022_auto_20220822_2319.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-08-22 14:19
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0021_templocation'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='shapelayers',
|
||||||
|
name='layerof',
|
||||||
|
field=models.IntegerField(choices=[(1, 'templocation'), (2, 'Location_line'), (3, 'Location_polygon')], default=1),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='templocation',
|
||||||
|
name='cp',
|
||||||
|
field=models.FloatField(default=0, null=True, verbose_name='Check Point'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
rog/migrations_backup/0023_alter_location_cp.py
Normal file
18
rog/migrations_backup/0023_alter_location_cp.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-08-22 14:19
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0022_auto_20220822_2319'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='cp',
|
||||||
|
field=models.FloatField(default=0, null=True, verbose_name='Check Point'),
|
||||||
|
),
|
||||||
|
]
|
||||||
18
rog/migrations_backup/0024_customuser_group.py
Normal file
18
rog/migrations_backup/0024_customuser_group.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-08-29 14:11
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0023_alter_location_cp'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customuser',
|
||||||
|
name='group',
|
||||||
|
field=models.CharField(choices=[('G1', '大垣-初心者'), ('G2', '大垣-3時間'), ('G3', '大垣-5時間')], default='G1', max_length=2),
|
||||||
|
),
|
||||||
|
]
|
||||||
23
rog/migrations_backup/0025_userupload.py
Normal file
23
rog/migrations_backup/0025_userupload.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2022-08-30 05:26
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import rog.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0024_customuser_group'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='UserUpload',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=255, verbose_name='User uploads')),
|
||||||
|
('file', models.FileField(blank=True, upload_to=rog.models.get_file_path)),
|
||||||
|
('uploaded_date', models.DateField(auto_now_add=True)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user