mirror of
https://github.com/rjNemo/villafleurie
synced 2026-06-12 13:26:47 +00:00
Push new bookings to master calendar
This commit is contained in:
parent
3f250f6ec6
commit
1e175cae9c
4 changed files with 85 additions and 71 deletions
26
README.md
26
README.md
|
|
@ -19,9 +19,26 @@ Le visiteur doit pouvoir :
|
||||||
- pouvoir contacter les propriétaires,
|
- pouvoir contacter les propriétaires,
|
||||||
- et pouvoir réserver
|
- et pouvoir réserver
|
||||||
|
|
||||||
## Structure
|
## Architecture
|
||||||
|
|
||||||
### Pages
|
### Front-end
|
||||||
|
|
||||||
|
- `Bootstrap 4`
|
||||||
|
- `Javascript`
|
||||||
|
- `JQuery`
|
||||||
|
|
||||||
|
### Back-end
|
||||||
|
|
||||||
|
- `Django 3.0`
|
||||||
|
- `PostgreSQL`
|
||||||
|
- `Docker`
|
||||||
|
- `NginX`
|
||||||
|
|
||||||
|
### Hébergement
|
||||||
|
|
||||||
|
- Virtual Private Server
|
||||||
|
|
||||||
|
## Pages
|
||||||
|
|
||||||
1. Page d'accueil
|
1. Page d'accueil
|
||||||
|
|
||||||
|
|
@ -48,7 +65,7 @@ Le visiteur doit pouvoir :
|
||||||
6. Page légale
|
6. Page légale
|
||||||
7. Page services
|
7. Page services
|
||||||
|
|
||||||
### Données
|
## Données
|
||||||
|
|
||||||
1. Logement :
|
1. Logement :
|
||||||
|
|
||||||
|
|
@ -99,10 +116,7 @@ Le visiteur doit pouvoir :
|
||||||
- Centrer Bouton "Reserver" page location
|
- Centrer Bouton "Reserver" page location
|
||||||
- Ajouter un titre "Disponibilités" au dessus du calendrier
|
- Ajouter un titre "Disponibilités" au dessus du calendrier
|
||||||
- page réservation/services : égayer avec des petites photos …
|
- page réservation/services : égayer avec des petites photos …
|
||||||
- Are guest unique ?
|
|
||||||
|
|
||||||
## BUGS
|
## BUGS
|
||||||
|
|
||||||
- La synchro ne gère pas les heures dans le calendriers.
|
- La synchro ne gère pas les heures dans le calendriers.
|
||||||
|
|
||||||
élminer les variables inutiles dans synchro_calendar
|
|
||||||
|
|
|
||||||
|
|
@ -11,15 +11,13 @@ import pickle
|
||||||
from villafleurie.settings import BASE_DIR
|
from villafleurie.settings import BASE_DIR
|
||||||
|
|
||||||
|
|
||||||
def synchronize_calendars(place):
|
def build_calendar_api_service():
|
||||||
"""
|
"""
|
||||||
Get a complete list of existing bookings in calendar
|
Build Google Calendar API service and returns calendar list and service
|
||||||
Creates reservation if not in db, update if already in db
|
|
||||||
Delete from db reservation deleted from cal
|
|
||||||
"""
|
"""
|
||||||
creds = None
|
creds = None
|
||||||
# If modifying these scopes, delete the file token.pickle.
|
# If modifying these scopes, delete the file token.pickle.
|
||||||
SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
|
SCOPES = ['https://www.googleapis.com/auth/calendar']
|
||||||
# The file token.pickle stores the user's access and refresh tokens, and is
|
# The file token.pickle stores the user's access and refresh tokens, and is
|
||||||
# created automatically when the authorization flow completes for the first
|
# created automatically when the authorization flow completes for the first
|
||||||
# time.
|
# time.
|
||||||
|
|
@ -32,24 +30,29 @@ def synchronize_calendars(place):
|
||||||
creds.refresh(Request())
|
creds.refresh(Request())
|
||||||
else:
|
else:
|
||||||
SECRETS = os.path.join(BASE_DIR, 'rental/client_secrets.json')
|
SECRETS = os.path.join(BASE_DIR, 'rental/client_secrets.json')
|
||||||
flow = InstalledAppFlow.from_client_secrets_file(SECRETS, scopes=SCOPES,
|
flow = InstalledAppFlow.from_client_secrets_file(
|
||||||
redirect_uri="http://localhost:8080/")
|
SECRETS, scopes=SCOPES, redirect_uri="http://localhost:8080/")
|
||||||
creds = flow.run_local_server()
|
creds = flow.run_local_server()
|
||||||
# Save the credentials for the next run
|
# Save the credentials for the next run
|
||||||
with open('token.pickle', 'wb') as token:
|
with open('token.pickle', 'wb') as token:
|
||||||
pickle.dump(creds, token)
|
pickle.dump(creds, token)
|
||||||
|
|
||||||
service = build('calendar', 'v3', credentials=creds)
|
service = build('calendar', 'v3', credentials=creds)
|
||||||
calendar = place.name
|
|
||||||
calendars = {
|
calendars = {
|
||||||
'T2': "burik7aclvhc7vsboh06c179uo@group.calendar.google.com",
|
'T2': "burik7aclvhc7vsboh06c179uo@group.calendar.google.com",
|
||||||
'T3': "fu7h30p0gk4a2p4nvo7nsbgpok@group.calendar.google.com"
|
'T3': "fu7h30p0gk4a2p4nvo7nsbgpok@group.calendar.google.com"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return service, calendars
|
||||||
|
|
||||||
|
|
||||||
|
def get_calendar_reservations(place):
|
||||||
|
service, calendars = build_calendar_api_service()
|
||||||
now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time
|
now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time
|
||||||
|
|
||||||
# for calendar in calendars:
|
|
||||||
events_result = service.events().list(
|
events_result = service.events().list(
|
||||||
calendarId=calendars[calendar],
|
calendarId=calendars[place.name],
|
||||||
timeMin=now,
|
timeMin=now,
|
||||||
singleEvents=True,
|
singleEvents=True,
|
||||||
orderBy='startTime'
|
orderBy='startTime'
|
||||||
|
|
@ -60,43 +63,52 @@ def synchronize_calendars(place):
|
||||||
else:
|
else:
|
||||||
for event in events:
|
for event in events:
|
||||||
reservation = {
|
reservation = {
|
||||||
'place': calendar.strip(),
|
'place': place.name.strip(),
|
||||||
'guest': event['summary'].strip(),
|
'guest': event['summary'].strip(),
|
||||||
'start': event['start'].get('dateTime', event['start'].get('date')).strip(),
|
'start': event['start'].get('dateTime', event['start'].get('date')).strip(),
|
||||||
'end': event['end'].get('dateTime', event['end'].get('date')).strip()
|
'end': event['end'].get('dateTime', event['end'].get('date')).strip()
|
||||||
}
|
}
|
||||||
|
return reservation
|
||||||
|
|
||||||
place = get_object_or_404(Place, name=calendar)
|
|
||||||
price = get_reservation_price(
|
|
||||||
place, reservation['start'], reservation['end'])
|
|
||||||
start = reservation['start']
|
|
||||||
end = reservation['end']
|
|
||||||
|
|
||||||
guest = Guest.objects.filter(name=reservation['guest'])
|
def synchronize_calendars(place):
|
||||||
if not guest.exists():
|
"""
|
||||||
guest = Guest.objects.create(name=reservation['guest'])
|
Get a complete list of existing bookings in calendar
|
||||||
else:
|
Creates reservation if not in db, update if already in db
|
||||||
# guest = guest[0]
|
Delete from db reservation deleted from cal
|
||||||
guest = guest.first()
|
"""
|
||||||
|
reservation = get_calendar_reservations(place)
|
||||||
|
|
||||||
db_booking = Reservation.objects.filter(
|
place = get_object_or_404(Place, name=place.name)
|
||||||
guest=guest
|
price = get_reservation_price(
|
||||||
)
|
place, reservation['start'], reservation['end'])
|
||||||
|
start = reservation['start']
|
||||||
|
end = reservation['end']
|
||||||
|
|
||||||
if not db_booking.exists():
|
guest = Guest.objects.filter(name=reservation['guest'])
|
||||||
Reservation.objects.create(
|
if not guest.exists():
|
||||||
place=place,
|
guest = Guest.objects.create(name=reservation['guest'])
|
||||||
guest=guest,
|
else:
|
||||||
start=start,
|
guest = guest.first()
|
||||||
end=end,
|
|
||||||
price=price
|
db_booking = Reservation.objects.filter(
|
||||||
)
|
guest=guest
|
||||||
else:
|
)
|
||||||
db_booking.place = place,
|
|
||||||
db_booking.guest = guest,
|
if not db_booking.exists():
|
||||||
db_booking.start = start,
|
Reservation.objects.create(
|
||||||
db_booking.end = end,
|
place=place,
|
||||||
db_booking.price = price
|
guest=guest,
|
||||||
|
start=start,
|
||||||
|
end=end,
|
||||||
|
price=price
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
db_booking.place = place,
|
||||||
|
db_booking.guest = guest,
|
||||||
|
db_booking.start = start,
|
||||||
|
db_booking.end = end,
|
||||||
|
db_booking.price = price
|
||||||
|
|
||||||
|
|
||||||
def get_bookings(place):
|
def get_bookings(place):
|
||||||
|
|
@ -121,5 +133,15 @@ def check_availability(place, start_date, end_date):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
def update_calendar(reservation):
|
||||||
synchronize_calendars()
|
""" push new reservation to master calendar """
|
||||||
|
# authenticate and build service
|
||||||
|
# event.insert(calendarId, summary="Guest", description="Message", end, start )
|
||||||
|
service, calendars = build_calendar_api_service()
|
||||||
|
service.events().insert(
|
||||||
|
calendarId=calendars[reservation.place.name],
|
||||||
|
summary=reservation.guest.name,
|
||||||
|
description=reservation.message,
|
||||||
|
end=reservation.end,
|
||||||
|
start=reservation.start
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
Copyright (c) 2014 Owl
|
|
||||||
Modified work Copyright 2016-2018 David Deutsch
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
|
||||||
obtaining a copy of this software and associated documentation
|
|
||||||
files (the "Software"), to deal in the Software without
|
|
||||||
restriction, including without limitation the rights to use,
|
|
||||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
@ -6,7 +6,7 @@ from django.views.generic.base import TemplateView
|
||||||
from .forms import ReservationForm
|
from .forms import ReservationForm
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
from rental.pricing import get_reservation_price
|
from rental.pricing import get_reservation_price
|
||||||
from rental.bookings import check_availability, synchronize_calendars
|
from rental.bookings import check_availability, synchronize_calendars, update_calendar
|
||||||
# import sys
|
# import sys
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -123,6 +123,7 @@ def reservation(request):
|
||||||
end=end,
|
end=end,
|
||||||
price=price
|
price=price
|
||||||
)
|
)
|
||||||
|
update_calendar(reservation)
|
||||||
context = {
|
context = {
|
||||||
'reservation': reservation
|
'reservation': reservation
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue