gerge branch 'master' of https://gitea.prod.resk-u.ch/CLERC/Reskreen
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -375,3 +375,5 @@ media/
|
||||
/vehicles/migrations_save/
|
||||
/carnet_rouge/migrations/
|
||||
/collabs/migrations/
|
||||
db.sqlite3
|
||||
/Reskreen/my.cnf
|
21
Dockerfile
Normal file
21
Dockerfile
Normal file
@@ -0,0 +1,21 @@
|
||||
FROM python:alpine3.19
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
COPY crons_jobs /etc/cron.d/django_crons_jobs
|
||||
|
||||
RUN chmod 0644 /etc/cron.d/django_crons_jobs && crontab /etc/cron.d/django_crons_jobs && touch /var/log/cron.log
|
||||
|
||||
|
||||
|
||||
RUN apk update && apk add --no-cache mariadb-connector-c-dev && apk add --no-cache gcc musl-dev openrc
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
RUN python manage.py makemigrations && python manage.py migrate
|
||||
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
CMD ["python", "manage.py", "runserver", "0.0.0.0:8080"]
|
||||
#CMD ["./startup.sh"]
|
||||
|
7
Reskreen/my_dev.cnf
Normal file
7
Reskreen/my_dev.cnf
Normal file
@@ -0,0 +1,7 @@
|
||||
[client]
|
||||
database = django_dev
|
||||
user = django_usr
|
||||
password = YwVHV36ovBTXWugb
|
||||
default-character-set = utf8
|
||||
host =33.144.144.3
|
||||
port =3306
|
11
Reskreen/rest_permission.py
Normal file
11
Reskreen/rest_permission.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from rest_framework import permissions
|
||||
class CustomPermission_DjangoModel_based(permissions.DjangoModelPermissions):
|
||||
perms_map = {
|
||||
'GET': ['%(app_label)s.view_%(model_name)s'],
|
||||
'OPTIONS': ['%(app_label)s.view_%(model_name)s'],
|
||||
'HEAD': ['%(app_label)s.view_%(model_name)s'],
|
||||
'POST': ['%(app_label)s.add_%(model_name)s'],
|
||||
'PUT': ['%(app_label)s.change_%(model_name)s'],
|
||||
'PATCH': ['%(app_label)s.change_%(model_name)s'],
|
||||
'DELETE': ['%(app_label)s.delete_%(model_name)s'],
|
||||
}
|
@@ -12,7 +12,7 @@ https://docs.djangoproject.com/en/4.0/ref/settings/
|
||||
|
||||
from pathlib import Path
|
||||
import os
|
||||
from .server_config import *
|
||||
from Reskreen.server_config import *
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
@@ -30,6 +30,8 @@ DEBUG = cfg_dev_mode
|
||||
ALLOWED_HOSTS = ["rh.ambulance-clerc.ch"]
|
||||
if cfg_dev_mode:
|
||||
ALLOWED_HOSTS.append("127.0.0.1")
|
||||
ALLOWED_HOSTS.append("33.144.144.6")
|
||||
ALLOWED_HOSTS.append("33.144.144.13")
|
||||
CSRF_TRUSTED_ORIGINS = ['https://rh.ambulance-clerc.ch']
|
||||
|
||||
|
||||
@@ -37,6 +39,7 @@ CSRF_TRUSTED_ORIGINS = ['https://rh.ambulance-clerc.ch']
|
||||
LOGIN_REDIRECT_URL = '/admin'
|
||||
INSTALLED_APPS = [
|
||||
'jazzmin',
|
||||
'django_cron',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
@@ -55,6 +58,20 @@ INSTALLED_APPS = [
|
||||
'django_summernote',
|
||||
]
|
||||
|
||||
INSTALLED_APPS += ( 'apilog.apps.ApilogConfig',)
|
||||
INSTALLED_APPS += ( 'corsheaders',)
|
||||
'',
|
||||
|
||||
#Ajout de rest_framework
|
||||
INSTALLED_APPS += ('rest_framework', 'rest_framework.authtoken',)
|
||||
'''REST_FRAMEWORK = {
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'rest_framework.authentication.TokenAuthentication', #Todo prod: replace by TokenAuthentication
|
||||
),
|
||||
# Autres paramètres de configuration...
|
||||
}'''
|
||||
|
||||
|
||||
LANGUAGE_CODE = 'fr-CH'
|
||||
|
||||
if not cfg_dev_mode:
|
||||
@@ -104,6 +121,7 @@ DATA_UPLOAD_MAX_NUMBER_FIELDS = 2500
|
||||
|
||||
|
||||
MIDDLEWARE = [
|
||||
'corsheaders.middleware.CorsMiddleware',
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'whitenoise.middleware.WhiteNoiseMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
@@ -117,6 +135,22 @@ MIDDLEWARE = [
|
||||
'django.middleware.locale.LocaleMiddleware',
|
||||
]
|
||||
|
||||
CRON_CLASSES = [
|
||||
"mycaldav.cron.InitTaskSync",
|
||||
]
|
||||
|
||||
CORS_ALLOWED_ORIGINS = [
|
||||
"http://33.144.144.13:4173",
|
||||
"http://33.144.144.13:5173",
|
||||
"http://33.144.144.13:3000",
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
MIDDLEWARE += ('apilog.middleware.APILogMiddleware',)
|
||||
|
||||
|
||||
ROOT_URLCONF = 'Reskreen.urls'
|
||||
|
||||
TEMPLATES = [
|
||||
@@ -163,7 +197,7 @@ else:
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.mysql',
|
||||
'OPTIONS': {
|
||||
'read_default_file': 'my.cnf',
|
||||
'read_default_file': os.path.join(BASE_DIR, 'Reskreen/my.cnf'),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@@ -26,12 +26,15 @@ urlpatterns = [
|
||||
path('accounts/', admin.site.urls),
|
||||
path('collabs/', include('collabs.urls')),
|
||||
path('vehicules/', include('vehicles.urls')),
|
||||
path('comm-opmessage/', include('comm_op.urls')),
|
||||
path('caldav/', include('mycaldav.urls')),
|
||||
#path('collabs_hour/', include('collabs.urls')),
|
||||
path('carnet_rouge/', include('carnet_rouge.urls')),
|
||||
path('student_eval/', include('studenteval.urls')),
|
||||
path('summernote/', include('django_summernote.urls')),
|
||||
path('editor/', include('django_summernote.urls')),
|
||||
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
|
||||
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
|
0
apilog/__init__.py
Normal file
0
apilog/__init__.py
Normal file
15
apilog/admin.py
Normal file
15
apilog/admin.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from django.contrib import admin
|
||||
from .models import APILog
|
||||
|
||||
|
||||
@admin.register(APILog)
|
||||
class APILogAdmin(admin.ModelAdmin):
|
||||
list_display = ('user', 'request_url', 'request_params', 'request_method', 'request_body', 'request_timestamp')
|
||||
list_filter = ('user', 'request_method')
|
||||
search_fields = ('request_url',)
|
||||
ordering = ('-request_timestamp',)
|
||||
|
||||
actions = None
|
||||
|
||||
def has_delete_permission(self, request, obj=None):
|
||||
return False
|
6
apilog/apps.py
Normal file
6
apilog/apps.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ApilogConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'apilog'
|
27
apilog/middleware.py
Normal file
27
apilog/middleware.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from .models import APILog
|
||||
|
||||
class APILogMiddleware:
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
|
||||
def __call__(self, request):
|
||||
if not request.path.startswith('/admin'):
|
||||
|
||||
user = request.user if request.user.is_authenticated else None
|
||||
|
||||
|
||||
request_url = request.path
|
||||
|
||||
request_params = request.GET if request.GET else None
|
||||
|
||||
|
||||
request_method = request.method
|
||||
|
||||
|
||||
request_body = request.body.decode('utf-8')
|
||||
|
||||
|
||||
APILog.objects.create(user=user, request_url=request_url, request_params=request_params, request_method=request_method, request_body=request_body)
|
||||
|
||||
response = self.get_response(request)
|
||||
return response
|
22
apilog/models.py
Normal file
22
apilog/models.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
from django.db.models.signals import pre_delete
|
||||
from django.dispatch import receiver
|
||||
|
||||
|
||||
class APILog(models.Model):
|
||||
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True)
|
||||
request_url = models.URLField()
|
||||
request_params = models.CharField(max_length=255, null=True, blank=True)
|
||||
request_method = models.CharField(max_length=10)
|
||||
request_body = models.TextField()
|
||||
request_timestamp = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.user} - {self.request_url}"
|
||||
|
||||
|
||||
@receiver(pre_delete, sender=APILog)
|
||||
def prevent_delete(sender, instance, **kwargs):
|
||||
# Empêchez la suppression en levant une exception, par exemple ValueError
|
||||
raise ValueError("Vous n'êtes pas autorisé à supprimer cet enregistrement.")
|
3
apilog/tests.py
Normal file
3
apilog/tests.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
3
apilog/views.py
Normal file
3
apilog/views.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
8
comm_op/serializers.py
Normal file
8
comm_op/serializers.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from rest_framework import serializers
|
||||
|
||||
from.models import comm_opMessage
|
||||
|
||||
class cl_comm_opMessage_Serializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = comm_opMessage
|
||||
fields = '__all__'
|
15
comm_op/urls.py
Normal file
15
comm_op/urls.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from django.urls import path, include
|
||||
from rest_framework import routers
|
||||
|
||||
|
||||
from . import views
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.register(r'api-comm-opmessage', views.comm_opMessageViewset, basename='comm-opmessage')
|
||||
|
||||
app_name = "comm_opMessage"
|
||||
urlpatterns = [
|
||||
path('', include(router.urls)),
|
||||
|
||||
]
|
||||
|
@@ -1,3 +1,12 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
from comm_op.models import *
|
||||
from rest_framework import viewsets
|
||||
from Reskreen.rest_permission import CustomPermission_DjangoModel_based
|
||||
|
||||
from .serializers import cl_comm_opMessage_Serializer
|
||||
|
||||
class comm_opMessageViewset(viewsets.ModelViewSet):
|
||||
queryset = comm_opMessage.objects.all()
|
||||
serializer_class = cl_comm_opMessage_Serializer
|
||||
permission_classes = [CustomPermission_DjangoModel_based]
|
5
compile_and_start_cont.sh
Executable file
5
compile_and_start_cont.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
docker build -t reskreen:dev .
|
||||
docker stop reskreen-validation && docker rm reskreen-validation
|
||||
docker stop reskreen-validation-cron && docker rm reskreen-validation-cron
|
||||
docker run -p 8080:8080 -d --name reskreen-validation -v /home/reskreen:/app/Reskreen reskreen:dev
|
||||
docker run -d --name reskreen-validation-cron -v /home/reskreen:/app/Reskreen reskreen:dev crond -f
|
2
crons_jobs
Normal file
2
crons_jobs
Normal file
@@ -0,0 +1,2 @@
|
||||
# Exécute la tâche cron toutes les heures
|
||||
* * * * * cd /app && python /app/manage.py runcrons > /var/log/runcrons.log
|
@@ -1,3 +1,8 @@
|
||||
from django.contrib import admin
|
||||
from mycaldav.models import caldav_sync_manager
|
||||
|
||||
|
||||
@admin.register(caldav_sync_manager)
|
||||
class caldav_sync_managerAdmin(admin.ModelAdmin):
|
||||
list_display = ('dtDate',)
|
||||
|
||||
# Register your models here.
|
||||
|
@@ -4,3 +4,4 @@ from django.apps import AppConfig
|
||||
class CaldavConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'mycaldav'
|
||||
|
||||
|
22
mycaldav/cron.py
Normal file
22
mycaldav/cron.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from django_cron import CronJobBase, Schedule
|
||||
import django
|
||||
|
||||
|
||||
|
||||
class InitTaskSync(CronJobBase):
|
||||
RUN_AT_TIMES = ['07:00', '19:00']
|
||||
RUN_EVERY_MIN = 1
|
||||
|
||||
schedule = Schedule(run_at_times=RUN_AT_TIMES,)
|
||||
code = 'reskreen.init_sync_task' # Un code unique pour votre tâche cron
|
||||
|
||||
def do(self):
|
||||
django.setup()
|
||||
|
||||
from mycaldav.models import caldav_sync_manager
|
||||
from mycaldav.settings import CALDAV_URL,CALDAV_USER,CALDAV_PASSWORD
|
||||
o_caldav_sync_management = caldav_sync_manager()
|
||||
o_caldav_sync_management.init_caldav(caldav_url=CALDAV_URL, caldav_user=CALDAV_USER, caldav_password=CALDAV_PASSWORD)
|
||||
o_caldav_sync_management.init_task_management()
|
||||
|
||||
print('Ma tâche cron s\'exécute !')
|
@@ -1,3 +1,4 @@
|
||||
from django.db import models
|
||||
from datetime import datetime, timedelta, time
|
||||
from django.contrib.auth.models import User
|
||||
import datetime as Datetime
|
||||
@@ -17,9 +18,82 @@ import recurring_ical_events
|
||||
import caldav
|
||||
|
||||
from mycaldav.settings import *
|
||||
import pytz
|
||||
from dateutil.parser import parse
|
||||
|
||||
Key_separator = "--"
|
||||
|
||||
|
||||
class caldav_sync_manager(models.Model):
|
||||
dtDate = models.DateField('Date_synchronized', auto_now_add=True, unique=True)
|
||||
bDone = models.BooleanField("Effectuée", default=False)
|
||||
dtUpdated = models.DateTimeField('date updated', auto_now=True)
|
||||
dtCreated = models.DateTimeField('date published', auto_now_add=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.dtDate}"
|
||||
|
||||
def init_caldav(self, caldav_url, caldav_user, caldav_password):
|
||||
client = caldav.DAVClient(url=caldav_url, username=caldav_user, password=caldav_password)
|
||||
data = client.principal()
|
||||
|
||||
self.a_task = data.calendar(cal_id=caldav_id["task"])
|
||||
|
||||
def set_today_as_synced(self):
|
||||
o_new_manager = caldav_sync_manager()
|
||||
o_new_manager.save()
|
||||
|
||||
def init_task_management(self):
|
||||
today = datetime.now()
|
||||
o_caldav_sync_management = caldav_sync_manager.objects.filter(dtDate=today.date())
|
||||
if not o_caldav_sync_management.exists():
|
||||
self.copy_caldav_data()
|
||||
print(f"synced events")
|
||||
else:
|
||||
print("pas de copy, sync déjà fait")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def copy_caldav_data(self,):
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
|
||||
today = datetime.now()
|
||||
seeked_date = today + relativedelta(months=1)
|
||||
sync_date = today + relativedelta(months=1, days=1)
|
||||
modified_url = caldav_cfg["task_config"] + f"&start={int(today.timestamp())}&end={int(sync_date.timestamp())}&expand=1"
|
||||
|
||||
with urllib.request.urlopen(modified_url, context=ctx) as o_url:
|
||||
sabre_data = o_url.read()
|
||||
|
||||
events = recurring_ical_events.of(Calendar.from_ical(sabre_data)).at((seeked_date.year,seeked_date.month,seeked_date.day))
|
||||
#print(f"events:{events}")
|
||||
|
||||
|
||||
for event in events:
|
||||
print(f"copy de l'événement: {event['SUMMARY']}")
|
||||
|
||||
|
||||
_title = event["SUMMARY"] if ("SUMMARY" in event) else "Sans Titre"
|
||||
_desc = event["DESCRIPTION"] if ("DESCRIPTION" in event) else ""
|
||||
|
||||
my_event = self.a_task.save_event(
|
||||
dtstart=event["DTSTART"].dt,
|
||||
dtend=event["DTEND"].dt,
|
||||
summary= _title,
|
||||
description= _desc,
|
||||
)
|
||||
self.set_today_as_synced()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Create your models here.
|
||||
class cls_caldav():
|
||||
url = ""
|
||||
@@ -46,22 +120,29 @@ class cls_caldav():
|
||||
self.day.sort(key=lambda x: x.key, reverse=reverse)
|
||||
self.night.sort(key=lambda x: x.key, reverse=reverse)
|
||||
|
||||
|
||||
|
||||
def get_caldav_data(self,periode=1,calendar=None, date=None):
|
||||
def caldav_open_url(self, days_delta, date):
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
|
||||
self.clear_data()
|
||||
|
||||
o_url = urllib.request.urlopen(self.url, context=ctx)
|
||||
self.data = o_url.read()
|
||||
o_url.close()
|
||||
|
||||
modified_url = self.url + f"&start={int((date-timedelta(days=days_delta)).timestamp())}&end={int((date +timedelta(days=days_delta)).timestamp())}&expand=1"
|
||||
print(f"ICS CALL URL = {modified_url}")
|
||||
with urllib.request.urlopen(modified_url, context=ctx) as o_url:
|
||||
self.data = o_url.read()
|
||||
|
||||
return self.data
|
||||
|
||||
def get_caldav_data(self,periode=1,calendar=None, date=None):
|
||||
if date is None:
|
||||
date = datetime.now()
|
||||
|
||||
self.caldav_open_url(days_delta=periode,date=date)
|
||||
|
||||
|
||||
|
||||
today = (date.year,date.month,date.day)
|
||||
|
||||
|
||||
@@ -81,11 +162,29 @@ class cls_caldav():
|
||||
events = recurring_ical_events.of(Calendar.from_ical(self.data)).between(today,endweek)
|
||||
|
||||
self.parse_data(events)
|
||||
|
||||
def convert_to_gmt1(self, dt):
|
||||
gmt1_tz = pytz.timezone('Europe/Paris')
|
||||
try:
|
||||
|
||||
if hasattr(dt,"tzinfo") and dt.tzinfo is not None:
|
||||
# Convertir l'objet datetime en GMT+1
|
||||
# Utilisez le nom de votre fuseau horaire GMT+1
|
||||
dt_gmt1 = dt.astimezone(gmt1_tz)
|
||||
else:
|
||||
# L'objet datetime est naïf, ajouter l'information de fuseau horaire GMT+1
|
||||
utc_tz = pytz.utc
|
||||
dt_utc = utc_tz.localize(dt)
|
||||
dt_gmt1 = dt_utc.astimezone(gmt1_tz)
|
||||
return dt_gmt1
|
||||
except:
|
||||
return dt
|
||||
def parse_data(self, events):
|
||||
desired_timezone = pytz.timezone('Europe/Paris')
|
||||
for event in events:
|
||||
item = _caldav_item()
|
||||
item.name = event["SUMMARY"]
|
||||
item.uiid = event["UID"]
|
||||
item.uuid = f"{event['UID']}"
|
||||
if Key_separator in item.name:
|
||||
arr = item.name.split(Key_separator)
|
||||
item.key = arr[0]
|
||||
@@ -107,23 +206,33 @@ class cls_caldav():
|
||||
item.team_2_chef = True
|
||||
item.team_2 = item.team_2.replace("#", "")
|
||||
|
||||
|
||||
if "DESCRIPTION" in event.keys():
|
||||
item.desc = event["DESCRIPTION"]
|
||||
if "#" in item.desc:
|
||||
item.done = True
|
||||
item.desc = f"{event['DESCRIPTION']}"
|
||||
|
||||
if "#Fait" in item.desc:
|
||||
item.done = True
|
||||
item.desc = item.desc.replace("#Fait", "")
|
||||
|
||||
|
||||
if '{href=' in item.desc:
|
||||
temp_str = item.desc.split('{href=')[1]
|
||||
temp_str = temp_str.split('}')[0]
|
||||
item.href = temp_str
|
||||
item.desc = item.desc.replace("{href=" + item.href + "}","")
|
||||
|
||||
item.dtstart = event["DTSTART"].dt.strftime("%d.%m.%Y %H:%M")
|
||||
item.dtstamp = int(event["DTSTART"].dt.strftime("%Y%m%d%H%M"))
|
||||
|
||||
desired_timezone = pytz.timezone('Europe/Paris')
|
||||
datetime_obj = parse(event["DTSTART"].dt.strftime("%d.%m.%Y %H:%M"))
|
||||
gmt1_datetime = datetime_obj.astimezone(desired_timezone)
|
||||
|
||||
print(f"gmt= {self.convert_to_gmt1( event['DTSTART'].dt)}")
|
||||
|
||||
|
||||
item.dtstart = self.convert_to_gmt1( event['DTSTART'].dt).strftime("%d.%m.%Y %H:%M")
|
||||
item.dtstamp = int(self.convert_to_gmt1( event['DTSTART'].dt).strftime("%Y%m%d%H%M"))
|
||||
#print(item.dtstamp)
|
||||
item.dtend = event["DTEND"].dt.strftime("%d.%m.%Y %H:%M")
|
||||
item.dtend = self.convert_to_gmt1( event['DTEND'].dt).strftime("%d.%m.%Y %H:%M")
|
||||
|
||||
|
||||
item.format_str_date()
|
||||
@@ -156,13 +265,17 @@ class cls_caldav_client():
|
||||
|
||||
caldav_agenda_config_url = caldav_cfg["task_config"]
|
||||
|
||||
|
||||
events = None
|
||||
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.client = caldav.DAVClient(url=self.caldav_url, username=self.caldav_user, password=self.caldav_password)
|
||||
self.data = self.client.principal()
|
||||
|
||||
|
||||
|
||||
def init_caldav(self, caldav_url, caldav_user, caldav_password):
|
||||
client = caldav.DAVClient(url=caldav_url, username=caldav_user, password=caldav_password)
|
||||
self.data = client.principal()
|
||||
|
||||
for cal in self.data.calendars():
|
||||
print(f"name: {cal.name}({cal.url})")
|
||||
@@ -176,7 +289,6 @@ class cls_caldav_client():
|
||||
self.a_rh = self.data.calendar(cal_id=caldav_id["rh"])
|
||||
self.a_manif = self.data.calendar(cal_id=caldav_id["manif"])
|
||||
|
||||
#self.get_events_by_date(self.a_team)
|
||||
def get_event_by_uuid(self,calandar,uuid):
|
||||
event = calandar.object_by_uid(uid=uuid)
|
||||
return event
|
||||
@@ -202,33 +314,6 @@ class cls_caldav_client():
|
||||
event.delete()
|
||||
|
||||
|
||||
|
||||
def init_task_management(self):
|
||||
print("pass copy task process")
|
||||
try:
|
||||
with open(os.path.join("mycaldav", "last_sync_config.bin"), "rb") as file:
|
||||
array = pickle.load(file)
|
||||
except:
|
||||
array = {"year": 0, "month": 0}
|
||||
print("Erreur lecture fichier config")
|
||||
|
||||
if array["month"] == datetime.now().month:
|
||||
if array["year"] == datetime.now().year:
|
||||
print("pas de copy, sync déjà fait")
|
||||
else:
|
||||
self.copy_caldav_data(self.a_task)
|
||||
else:
|
||||
self.copy_caldav_data(self.a_task)
|
||||
self.clear_all_events_by_Date(self.a_task)
|
||||
|
||||
|
||||
def add_event_in_calandar(self, calandar):
|
||||
my_event = calandar.save_event(
|
||||
dtstart=datetime(2022, 6, 30, 12),
|
||||
dtend=datetime(2022, 6, 30, 13),
|
||||
summary="Do the needful",
|
||||
|
||||
)
|
||||
def get_events_by_date(self,calandar,date=None ):
|
||||
if date is None:
|
||||
date = datetime.now()
|
||||
@@ -297,126 +382,33 @@ class cls_caldav_client():
|
||||
|
||||
|
||||
|
||||
def copy_caldav_data(self, calandar=None):
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
|
||||
|
||||
|
||||
o_url = urllib.request.urlopen(self.caldav_agenda_config_url, context=ctx)
|
||||
data = o_url.read()
|
||||
o_url.close()
|
||||
|
||||
now = f"01.{datetime.now().month}.{datetime.now().year}"
|
||||
|
||||
|
||||
next_month = datetime.strptime(f"1.{datetime.today().month}.{datetime.today().year}","%d.%m.%Y") + relativedelta(months=1)
|
||||
next_month = (next_month.year, next_month.month, next_month.day)
|
||||
|
||||
today = (datetime.now().year, datetime.now().month, 1)
|
||||
print(f"today:{today}")
|
||||
print(f"next:{next_month}")
|
||||
events = None
|
||||
events = recurring_ical_events.of(Calendar.from_ical(data)).between(today, next_month)
|
||||
cur_events = calandar.date_search(start=datetime(today[0],today[1],today[2]), end=datetime(next_month[0],next_month[1],next_month[2]), expand=True)
|
||||
|
||||
for event in events:
|
||||
print(f"copy de l'événement: {event['SUMMARY']}")
|
||||
|
||||
|
||||
_title = event["SUMMARY"] if ("SUMMARY" in event) else "Sans Titre"
|
||||
_desc = event["DESCRIPTION"] if ("DESCRIPTION" in event) else ""
|
||||
|
||||
my_event = calandar.save_event(
|
||||
dtstart=event["DTSTART"].dt,
|
||||
dtend=event["DTEND"].dt,
|
||||
summary= _title,
|
||||
description= _desc,
|
||||
)
|
||||
|
||||
with open(os.path.join("mycaldav", "last_sync_config.bin"), "wb") as file:
|
||||
array = {"year":datetime.now().year, "month":datetime.now().month}
|
||||
pickle.dump(array, file)
|
||||
|
||||
|
||||
|
||||
|
||||
def clear_all_events_by_Date(self, calandar):
|
||||
events = calandar.date_search(start=datetime(2000, 1, 1), end=datetime.now() - relativedelta(years=1), expand=True)
|
||||
for e in events:
|
||||
e.delete()
|
||||
#print(events)
|
||||
|
||||
def reformat_all_events(self,calandar):
|
||||
events = calandar.date_search(start=datetime(2023, 1, 1), end=datetime.now() + relativedelta(years=1),
|
||||
expand=True)
|
||||
|
||||
for event in events:
|
||||
summary = event.vobject_instance.vevent.summary.value
|
||||
print(f"test summary {summary}")
|
||||
if "----" in summary:
|
||||
summary = summary.replace("----", Key_separator)
|
||||
print(f"reformat: [{summary}]")
|
||||
event.vobject_instance.vevent.summary.value = summary
|
||||
event.save()
|
||||
elif "--" in summary:
|
||||
pass
|
||||
elif "-" in summary:
|
||||
summary = summary.replace("-",Key_separator)
|
||||
print(f"reformat: [{summary}]")
|
||||
event.vobject_instance.vevent.summary.value = summary
|
||||
event.save()
|
||||
|
||||
def change_utc_to_zurich_all_events(self,calandar):
|
||||
events = calandar.date_search(start=datetime(2023, 4, 1), end=datetime.now() + relativedelta(years=1),
|
||||
expand=True)
|
||||
|
||||
for event in events:
|
||||
start = event.vobject_instance.vevent.dtstart.value
|
||||
end = start + relativedelta(day=1)
|
||||
|
||||
if start.hour < 12:
|
||||
new_start = datetime(start.year, start.month, start.day,7,0,0, tzinfo = pytz.timezone("Europe/Zurich"))
|
||||
new_end = datetime(start.year, start.month, start.day, 19, 0, 0, tzinfo=pytz.timezone("Europe/Zurich"))
|
||||
elif start.hour > 12:
|
||||
new_start = datetime(start.year, start.month, start.day,19,0,0, tzinfo = pytz.timezone("Europe/Zurich"))
|
||||
new_end = datetime(start.year, start.month,start.day, 23, 59, 0, tzinfo=pytz.timezone("Europe/Zurich"))
|
||||
|
||||
event.vobject_instance.vevent.dtstart.value = new_start
|
||||
event.vobject_instance.vevent.dtend.value = new_end
|
||||
|
||||
|
||||
if new_end<new_start :
|
||||
print(f"{new_start}>{new_end}")
|
||||
print("ERROR")
|
||||
event.vobject_instance.vevent.dtend.value = new_start
|
||||
|
||||
|
||||
event.save()
|
||||
|
||||
|
||||
|
||||
class _caldav_item():
|
||||
key = ""
|
||||
name = ""
|
||||
desc = ""
|
||||
dtstart = None
|
||||
str_start_date = ""
|
||||
str_start_time = ""
|
||||
dtend = None
|
||||
str_end_date = ""
|
||||
str_end_time = ""
|
||||
dtstamp = None
|
||||
done = False
|
||||
href = ""
|
||||
uiid = ""
|
||||
team_1 = ""
|
||||
team_2 = ""
|
||||
team_1_chef = False
|
||||
team_2_chef = False
|
||||
team_transfert = False
|
||||
team_manif = False
|
||||
def __init__(self, key="", name="", desc="", dtstart=None, str_start_date="",
|
||||
str_start_time="", dtend=None, str_end_date="", str_end_time="",
|
||||
dtstamp=None, done=False, href="", uuid="", team_1="",
|
||||
team_2="", team_1_chef=False, team_2_chef=False,
|
||||
team_transfert=False, team_manif=False):
|
||||
self.key = key
|
||||
self.name = name
|
||||
self.desc = desc
|
||||
self.dtstart = dtstart
|
||||
self.str_start_date = str_start_date
|
||||
self.str_start_time = str_start_time
|
||||
self.dtend = dtend
|
||||
self.str_end_date = str_end_date
|
||||
self.str_end_time = str_end_time
|
||||
self.dtstamp = dtstamp
|
||||
self.done = done
|
||||
self.href = href
|
||||
self.uuid = uuid
|
||||
self.team_1 = team_1
|
||||
self.team_2 = team_2
|
||||
self.team_1_chef = team_1_chef
|
||||
self.team_2_chef = team_2_chef
|
||||
self.team_transfert = team_transfert
|
||||
self.team_manif = team_manif
|
||||
|
||||
def format_str_date(self):
|
||||
self.str_start_date = datetime.strptime(self.dtstart,"%d.%m.%Y %H:%M").strftime("%d.%m")
|
||||
@@ -427,3 +419,24 @@ class _caldav_item():
|
||||
|
||||
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
class CalDavItemSerializer(serializers.Serializer):
|
||||
key = serializers.CharField()
|
||||
name = serializers.CharField()
|
||||
desc = serializers.CharField(allow_blank=True)
|
||||
dtstart = serializers.CharField()
|
||||
str_start_date = serializers.CharField()
|
||||
str_start_time = serializers.CharField()
|
||||
dtend = serializers.CharField()
|
||||
str_end_date = serializers.CharField()
|
||||
str_end_time = serializers.CharField()
|
||||
done = serializers.BooleanField()
|
||||
href = serializers.CharField(allow_blank=True)
|
||||
uuid = serializers.CharField()
|
||||
team_1 = serializers.CharField(allow_blank=True)
|
||||
team_2 = serializers.CharField(allow_blank=True)
|
||||
team_1_chef = serializers.BooleanField()
|
||||
team_2_chef = serializers.BooleanField()
|
||||
team_transfert = serializers.BooleanField()
|
||||
team_manif = serializers.BooleanField()
|
@@ -13,3 +13,8 @@ for key,value in caldav_id.items():
|
||||
caldav_cfg[key] = f"https://sync.infomaniak.com/calendars/AA01593/{value}?export"
|
||||
|
||||
|
||||
CALDAV_URL = "https://sync.infomaniak.com"
|
||||
CALDAV_USER = 'AA01593' #agenda@ambulance-clerc.ch
|
||||
CALDAV_PASSWORD = "Agendamc144"
|
||||
|
||||
|
||||
|
@@ -7,13 +7,13 @@ from . import views
|
||||
app_name = "mycaldav"
|
||||
urlpatterns = [
|
||||
path('task', views.view_task_caldav, name='view_task_caldav'),
|
||||
path('task/edit/<str:uuid>', views.view_task_edit_caldav, name='view_task_edit_caldav'),
|
||||
path('task/edit', views.view_task_edit_caldav, name='view_task_edit_caldav'),
|
||||
path('vhc', views.view_vhc_caldav, name='view_vhc_caldav'),
|
||||
path('vhc/edit/<str:uuid>', views.view_vhc_edit_caldav, name='view_vhc_edit_caldav'),
|
||||
path('vhc/edit', views.view_vhc_edit_caldav, name='view_vhc_edit_caldav'),
|
||||
path('rh', views.view_rh_caldav, name='view_rh_caldav'),
|
||||
path('road', views.view_road_caldav, name='view_road_caldav'),
|
||||
path('op', views.view_op_caldav, name='view_op_caldav'),
|
||||
path('op/edit/<str:uuid>', views.view_op_edit_caldav, name='view_op_edit_caldav'),
|
||||
path('op/edit', views.view_op_edit_caldav, name='view_op_edit_caldav'),
|
||||
path('team', views.view_team_caldav, name='view_team_caldav'),
|
||||
path('manif', views.view_manif_caldav, name='view_manif_caldav'),
|
||||
path('team_pdf', views.view_team_pdf_caldav, name='view_team_pdf_caldav'),
|
||||
|
@@ -1,4 +1,6 @@
|
||||
from django.http import HttpResponse
|
||||
import json
|
||||
|
||||
from django.http import HttpResponse, JsonResponse
|
||||
from django.http import FileResponse
|
||||
from django.shortcuts import render
|
||||
from django.views import generic
|
||||
@@ -19,130 +21,203 @@ from mycaldav.settings import *
|
||||
from mycaldav.export_team_pdf import *
|
||||
from comm_op.models import comm_opMessage
|
||||
|
||||
class caldav_item:
|
||||
def __init__(self):
|
||||
self.uuid = ""
|
||||
self.name = ""
|
||||
self.desc = ""
|
||||
self.key = ""
|
||||
self.done = False
|
||||
self.href = "#"
|
||||
self.str_start_date = ""
|
||||
self.str_end_date = ""
|
||||
|
||||
from rest_framework.response import Response
|
||||
from rest_framework import status
|
||||
from rest_framework.decorators import api_view
|
||||
|
||||
from mycaldav.models import CalDavItemSerializer, _caldav_item
|
||||
from mycaldav.settings import CALDAV_URL,CALDAV_USER,CALDAV_PASSWORD
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def formatResponseArray(o_caldav, inverted=False):
|
||||
|
||||
try:
|
||||
if inverted:
|
||||
o_caldav.items.reverse()
|
||||
o_caldav.day.reverse()
|
||||
o_caldav.night.reverse()
|
||||
|
||||
@xframe_options_exempt
|
||||
# Serialize data
|
||||
serializer_items = CalDavItemSerializer(data=[item.__dict__ for item in o_caldav.items], many=True)
|
||||
serializer_day = CalDavItemSerializer(data=[item.__dict__ for item in o_caldav.day], many=True)
|
||||
serializer_night = CalDavItemSerializer(data=[item.__dict__ for item in o_caldav.night], many=True)
|
||||
|
||||
# Check validation and print errors
|
||||
validate_and_log(serializer_items, "items")
|
||||
validate_and_log(serializer_day, "day")
|
||||
validate_and_log(serializer_night, "night")
|
||||
|
||||
response_data = {
|
||||
"items": serializer_items.data,
|
||||
"day": serializer_day.data,
|
||||
"night": serializer_night.data,
|
||||
}
|
||||
response_status = status.HTTP_200_OK
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"An error occurred: {e}")
|
||||
response_data = {"error": "An error occurred while processing the request."}
|
||||
response_status = status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
|
||||
return {"data":response_data, "status": response_status}
|
||||
def validate_and_log(serializer, label):
|
||||
if not serializer.is_valid():
|
||||
print(f"Validation Error {label}: {serializer.errors}")
|
||||
@api_view(['GET'])
|
||||
def view_task_caldav(request):
|
||||
o_caldav = cls_caldav(url=caldav_cfg["task"])
|
||||
o_caldav.get_caldav_data()
|
||||
template = loader.get_template("task/task.html")
|
||||
context = {'latest_task_list':o_caldav.day, 'night_task_list': o_caldav.night}
|
||||
'''DEPRECATED
|
||||
if (datetime.today().day == 1) and 2==1:
|
||||
myClient = cls_caldav_client()
|
||||
myClient.init_task_management()'''
|
||||
return HttpResponse(template.render(context,request))
|
||||
'''
|
||||
o_caldav_sync_management = caldav_sync_manager()
|
||||
o_caldav_sync_management.init_caldav(caldav_url=CALDAV_URL, caldav_user=CALDAV_USER, caldav_password=CALDAV_PASSWORD)
|
||||
o_caldav_sync_management.init_task_management()
|
||||
'''
|
||||
|
||||
|
||||
response = formatResponseArray(o_caldav)
|
||||
return Response(response["data"], status=response["status"])
|
||||
|
||||
|
||||
|
||||
@api_view(['POST'])
|
||||
def view_task_edit_caldav(request):
|
||||
data = json.loads(request.body.decode('utf-8'))
|
||||
uuid = data.get('uuid', None)
|
||||
if uuid is None:
|
||||
# Gérer le cas où l'UUID n'est pas fourni dans les données JSON
|
||||
return JsonResponse({'error': 'UUID non fourni dans les données JSON'}, status=400)
|
||||
|
||||
@xframe_options_exempt
|
||||
def view_task_edit_caldav(request, uuid):
|
||||
print(uuid)
|
||||
myClient = cls_caldav_client()
|
||||
myClient.init_caldav(caldav_url=CALDAV_URL, caldav_user=CALDAV_USER, caldav_password=CALDAV_PASSWORD)
|
||||
myClient.mark_as_done_task(calandar=myClient.a_task,uuid=uuid)
|
||||
return view_task_caldav(request)
|
||||
return JsonResponse({'sucsess': 'UUID marqué à done'}, status=200)
|
||||
|
||||
def view_op_edit_caldav(request, uuid):
|
||||
print(uuid)
|
||||
|
||||
|
||||
@api_view(['POST'])
|
||||
def view_op_edit_caldav(request):
|
||||
data = json.loads(request.body.decode('utf-8'))
|
||||
uuid = data.get('uuid', None)
|
||||
if uuid is None:
|
||||
# Gérer le cas où l'UUID n'est pas fourni dans les données JSON
|
||||
return JsonResponse({'error': 'UUID non fourni dans les données JSON'}, status=400)
|
||||
object = comm_opMessage.objects.get(pk=uuid)
|
||||
object.bDone = True
|
||||
object.dtEnd = datetime.today()
|
||||
object.save()
|
||||
|
||||
return view_op_caldav(request)
|
||||
|
||||
def view_vhc_edit_caldav(request, uuid):
|
||||
print(uuid)
|
||||
return JsonResponse({'sucsess': 'UUID marqué à done'}, status=200)
|
||||
@api_view(['POST'])
|
||||
def view_vhc_edit_caldav(request):
|
||||
data = json.loads(request.body.decode('utf-8'))
|
||||
uuid = data.get('uuid', None)
|
||||
if uuid is None:
|
||||
# Gérer le cas où l'UUID n'est pas fourni dans les données JSON
|
||||
return JsonResponse({'error': 'UUID non fourni dans les données JSON'}, status=400)
|
||||
myClient = cls_caldav_client()
|
||||
myClient.init_caldav(caldav_url=CALDAV_URL, caldav_user=CALDAV_USER, caldav_password=CALDAV_PASSWORD)
|
||||
myClient.mark_as_done_task(calandar=myClient.a_vhc,uuid=uuid)
|
||||
return view_vhc_caldav(request)
|
||||
return JsonResponse({'sucsess': 'UUID marqué à done'}, status=200)
|
||||
|
||||
@xframe_options_exempt
|
||||
@api_view(['GET'])
|
||||
def view_vhc_caldav(request):
|
||||
o_caldav = cls_caldav(url=caldav_cfg["vhc"])
|
||||
o_caldav.get_caldav_data(periode=2)
|
||||
template = loader.get_template("vhc/vhc_view.html")
|
||||
context = {'latest_task_list': o_caldav.items}
|
||||
return HttpResponse(template.render(context, request))
|
||||
|
||||
@xframe_options_exempt
|
||||
response = formatResponseArray(o_caldav)
|
||||
return Response(response["data"], status=response["status"])
|
||||
|
||||
@api_view(['GET'])
|
||||
def view_rh_caldav(request):
|
||||
o_caldav = cls_caldav(url=caldav_cfg["rh"])
|
||||
o_caldav.get_caldav_data(periode=2)
|
||||
template = loader.get_template("rh/rh_view.html")
|
||||
context = {'latest_task_list': o_caldav.items[::-1], 'today': datetime.today().strftime('%d.%m')}
|
||||
return HttpResponse(template.render(context, request))
|
||||
|
||||
@xframe_options_exempt
|
||||
response = formatResponseArray(o_caldav,inverted=False)
|
||||
return Response(response["data"], status=response["status"])
|
||||
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
def view_road_caldav(request):
|
||||
o_caldav = cls_caldav(url=caldav_cfg["road"])
|
||||
o_caldav.get_caldav_data(periode=2)
|
||||
template = loader.get_template("road/road_view.html")
|
||||
context = {'latest_task_list': o_caldav.items[::-1]}
|
||||
return HttpResponse(template.render(context, request))
|
||||
@xframe_options_exempt
|
||||
def view_op_caldav(request):
|
||||
response = formatResponseArray(o_caldav, inverted=True)
|
||||
return Response(response["data"], status=response["status"])
|
||||
|
||||
|
||||
def close_old_op_message():
|
||||
old_items = comm_opMessage.objects.filter(bDone=False, dtEnd__lte=datetime.today() - timedelta(days=1))
|
||||
for old_item in old_items:
|
||||
old_item.bDone = True
|
||||
old_item.save()
|
||||
|
||||
@api_view(['GET'])
|
||||
def view_op_caldav(request):
|
||||
close_old_op_message()
|
||||
|
||||
o_items = comm_opMessage.objects.filter(Q(dtStart__lte= datetime.today() + timedelta(days=1)) & ( Q(dtEnd__gte=datetime.today()) | Q(dtEnd__isnull=True)))
|
||||
all_items = []
|
||||
for item in o_items:
|
||||
temp_item = caldav_item()
|
||||
temp_item.uuid = item.uuid
|
||||
temp_item = _caldav_item()
|
||||
temp_item.uuid = f"{item.uuid}"
|
||||
temp_item.name = item.sTitle
|
||||
temp_item.desc = item.sDesc
|
||||
temp_item.key = item.sKey
|
||||
temp_item.done = item.bDone
|
||||
temp_item.str_start_date = str(item.dtStart.day) + "." + str(item.dtStart.month)
|
||||
temp_item.str_start_date = str(item.dtStart.strftime('%d')) + "." + str(item.dtStart.strftime('%m'))
|
||||
if item.dtEnd != None:
|
||||
temp_item.str_end_date = str(item.dtEnd.day) + "." + str(item.dtEnd.month)
|
||||
temp_item.str_end_date = str(item.dtEnd.strftime('%d')) + "." + str(item.dtEnd.strftime('%m'))
|
||||
else:
|
||||
temp_item.str_end_date = None
|
||||
all_items.append(temp_item)
|
||||
|
||||
template = loader.get_template("op/op_view.html")
|
||||
context = {'latest_task_list': all_items}
|
||||
return HttpResponse(template.render(context, request))
|
||||
try:
|
||||
serializer = CalDavItemSerializer(data=all_items, many=True)
|
||||
if serializer.is_valid():
|
||||
print("Serialized Data:", serializer.data)
|
||||
else:
|
||||
print("Validation Error:", serializer.errors)
|
||||
|
||||
@xframe_options_exempt
|
||||
except Exception as e:
|
||||
logger.error(f"An error occurred: {e}")
|
||||
return Response({"error": "An error occurred while processing the request."},
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
return Response({"items":serializer.data})
|
||||
|
||||
@api_view(['GET'])
|
||||
def view_team_caldav(request):
|
||||
#Change timezone
|
||||
myclient = cls_caldav_client()
|
||||
#myclient.reformat_all_events(myclient.a_team)
|
||||
#myclient.change_utc_to_zurich_all_events(myclient.a_team)
|
||||
#myclient.reformat_all_events(myclient.a_task_config)
|
||||
#myclient.change_utc_to_zurich_all_events(myclient.a_task)
|
||||
|
||||
|
||||
o_caldav = cls_caldav(url=caldav_cfg["team"])
|
||||
o_caldav.get_caldav_data(periode=3)
|
||||
template = loader.get_template("team/team_view.html")
|
||||
o_caldav.sort_array_by_key(True)
|
||||
|
||||
context = {'latest_task_list': o_caldav.day, 'night_task_list': o_caldav.night, 'today': datetime.today().strftime('%d.%m'),'yesterday': (datetime.today() + timedelta(days=-1)).strftime('%d.%m'),'tomorow': (datetime.today() + timedelta(days=+1)).strftime('%d.%m')}
|
||||
return HttpResponse(template.render(context, request))
|
||||
response = formatResponseArray(o_caldav)
|
||||
additional_data = {
|
||||
'today': datetime.today().strftime('%d.%m'),
|
||||
'yesterday': (datetime.today() + timedelta(days=-1)).strftime('%d.%m'),
|
||||
'tomorrow': (datetime.today() + timedelta(days=1)).strftime('%d.%m')
|
||||
}
|
||||
response["data"].update(additional_data)
|
||||
return Response(response["data"], status=response["status"])
|
||||
|
||||
@xframe_options_exempt
|
||||
|
||||
@api_view(['GET'])
|
||||
def view_manif_caldav(request):
|
||||
o_caldav = cls_caldav(url=caldav_cfg["manif"])
|
||||
o_caldav.get_caldav_data(periode=1)
|
||||
template = loader.get_template("manif/manif_view.html")
|
||||
o_caldav.sort_array_by_key(True)
|
||||
context = {'latest_task_list': o_caldav.items, 'night_task_list': o_caldav.night, 'today': datetime.today().strftime('%d.%m')}
|
||||
return HttpResponse(template.render(context, request))
|
||||
|
||||
response = formatResponseArray(o_caldav)
|
||||
return Response(response["data"], status=response["status"])
|
||||
|
||||
|
||||
@xframe_options_exempt
|
||||
def view_team_pdf_caldav(request):
|
||||
@@ -153,6 +228,7 @@ def view_team_pdf_caldav(request):
|
||||
start = datetime.strptime(request.GET['dt'], "%d.%m.%Y")
|
||||
|
||||
myClient = cls_caldav_client()
|
||||
myClient.init_caldav(caldav_url=CALDAV_URL, caldav_user=CALDAV_USER, caldav_password=CALDAV_PASSWORD)
|
||||
render_pdf(o_caldav, caldavClient=myClient, date=start)
|
||||
return FileResponse(open('mycaldav/export.pdf', 'rb'), as_attachment=False, content_type='application/pdf')
|
||||
|
||||
|
@@ -1,57 +1,5 @@
|
||||
arabic-reshaper==2.1.3
|
||||
asgiref==3.7.2
|
||||
asn1crypto==1.5.1
|
||||
Brotli==1.0.9
|
||||
caldav==0.9.1
|
||||
certifi==2021.10.8
|
||||
cffi==1.15.0
|
||||
charset-normalizer==2.0.12
|
||||
click==8.1.3
|
||||
colorama==0.4.4
|
||||
cryptography==37.0.1
|
||||
cssselect2==0.4.1
|
||||
Django
|
||||
django-admin-rangefilter
|
||||
fpdf==1.7.2
|
||||
future==0.18.2
|
||||
html5lib==1.1
|
||||
icalendar==4.0.9
|
||||
idna==3.3
|
||||
lxml
|
||||
# mysqlclient==2.1.0
|
||||
oscrypto==1.3.0
|
||||
pdfkit==1.0.0
|
||||
Pillow==9.0.1
|
||||
pycparser==2.21
|
||||
pydyf==0.1.2
|
||||
pyHanko==0.13.1
|
||||
pyhanko-certvalidator==0.19.5
|
||||
PyPDF3==1.0.6
|
||||
pyphen==0.12.0
|
||||
python-bidi==0.4.2
|
||||
python-dateutil==2.8.2
|
||||
pytz==2022.1
|
||||
pytz-deprecation-shim==0.1.0.post0
|
||||
PyYAML==6.0
|
||||
qrcode==7.3.1
|
||||
recurring-ical-events==1.0.2b0
|
||||
reportlab==3.6.9
|
||||
requests==2.27.1
|
||||
six==1.16.0
|
||||
sqlparse==0.4.2
|
||||
svglib==1.2.1
|
||||
tinycss2==1.1.1
|
||||
tqdm==4.64.0
|
||||
tzdata==2021.5
|
||||
tzlocal==4.2
|
||||
uritools==4.0.0
|
||||
urllib3==1.26.9
|
||||
vobject==0.9.6.1
|
||||
weasyprint==54.1
|
||||
webencodings==0.5.1
|
||||
x-wr-timezone==0.0.5
|
||||
xhtml2pdf==0.2.7
|
||||
zopfli==0.1.9
|
||||
django-autologin
|
||||
django-summernote
|
||||
django-jazzmin
|
||||
@@ -59,3 +7,15 @@ django-default-language
|
||||
gunicorn
|
||||
whitenoise
|
||||
django-filter
|
||||
djangorestframework
|
||||
mysqlclient
|
||||
pyocclient
|
||||
django-cors-headers
|
||||
pytz
|
||||
python-dateutil
|
||||
icalendar
|
||||
recurring-ical-events
|
||||
caldav
|
||||
xhtml2pdf
|
||||
fpdf
|
||||
django-cron
|
7
startup.sh
Executable file
7
startup.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
# startup.sh
|
||||
# make sure errors stop execution
|
||||
set -e
|
||||
# start the cronjob
|
||||
crond -f -l 8 &
|
||||
# start nextjs using our own command from package.json...
|
||||
python /app/manage.py runserver 0.0.0.0:8080
|
14
vehicles/serializers.py
Normal file
14
vehicles/serializers.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from django.contrib.auth.models import User, Group
|
||||
from rest_framework import serializers
|
||||
|
||||
from.models import Vehicles_infos, Vehicles
|
||||
|
||||
class cl_Vehicles_Serializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Vehicles
|
||||
fields = '__all__'
|
||||
|
||||
class cl_Vehicles_infos_Serializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Vehicles_infos
|
||||
fields = '__all__'
|
@@ -1,14 +1,17 @@
|
||||
from django.urls import path
|
||||
|
||||
from django.urls import path, include
|
||||
from rest_framework import routers
|
||||
|
||||
|
||||
from . import views
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.register(r'api-vehicle', views.VehicleViewset, basename='vehicle')
|
||||
|
||||
app_name = "vehicles"
|
||||
urlpatterns = [
|
||||
path('vhc', views.view_vhc, name='view_vhc'),
|
||||
path('peremptions', views.view_peremptions, name='view_peremptions'),
|
||||
path('', include(router.urls)),
|
||||
|
||||
|
||||
|
||||
|
@@ -6,6 +6,20 @@ from django.template import loader
|
||||
from django.views.decorators.clickjacking import xframe_options_exempt
|
||||
|
||||
from vehicles.models import *
|
||||
from rest_framework import viewsets
|
||||
from Reskreen.rest_permission import CustomPermission_DjangoModel_based
|
||||
|
||||
from .serializers import cl_Vehicles_Serializer, cl_Vehicles_infos_Serializer
|
||||
|
||||
class VehicleViewset(viewsets.ModelViewSet):
|
||||
queryset = Vehicles.objects.all()
|
||||
serializer_class = cl_Vehicles_Serializer
|
||||
permission_classes = [CustomPermission_DjangoModel_based]
|
||||
|
||||
class VehicleViewset(viewsets.ModelViewSet):
|
||||
queryset = Vehicles.objects.all()
|
||||
serializer_class = cl_Vehicles_Serializer
|
||||
permission_classes = [CustomPermission_DjangoModel_based]
|
||||
|
||||
@xframe_options_exempt
|
||||
def view_vhc(request):
|
||||
|
Reference in New Issue
Block a user