From 1e175cae9cfa809c9afc98478960b3aed77ec30e Mon Sep 17 00:00:00 2001 From: Ruidy Nemausat Date: Sun, 15 Dec 2019 15:24:47 +0100 Subject: [PATCH] Push new bookings to master calendar --- README.md | 26 +++-- rental/bookings.py | 104 +++++++++++-------- rental/static/rental/lib/owlcarousel/LICENSE | 23 ---- rental/views.py | 3 +- 4 files changed, 85 insertions(+), 71 deletions(-) delete mode 100644 rental/static/rental/lib/owlcarousel/LICENSE diff --git a/README.md b/README.md index 89e59ec..e290c13 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,26 @@ Le visiteur doit pouvoir : - pouvoir contacter les propriétaires, - 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 @@ -48,7 +65,7 @@ Le visiteur doit pouvoir : 6. Page légale 7. Page services -### Données +## Données 1. Logement : @@ -99,10 +116,7 @@ Le visiteur doit pouvoir : - Centrer Bouton "Reserver" page location - Ajouter un titre "Disponibilités" au dessus du calendrier - page réservation/services : égayer avec des petites photos … -- Are guest unique ? ## BUGS - La synchro ne gère pas les heures dans le calendriers. - -élminer les variables inutiles dans synchro_calendar diff --git a/rental/bookings.py b/rental/bookings.py index e5e335d..dd6af9b 100644 --- a/rental/bookings.py +++ b/rental/bookings.py @@ -11,15 +11,13 @@ import pickle from villafleurie.settings import BASE_DIR -def synchronize_calendars(place): +def build_calendar_api_service(): """ - Get a complete list of existing bookings in calendar - Creates reservation if not in db, update if already in db - Delete from db reservation deleted from cal + Build Google Calendar API service and returns calendar list and service """ creds = None # 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 # created automatically when the authorization flow completes for the first # time. @@ -32,24 +30,29 @@ def synchronize_calendars(place): creds.refresh(Request()) else: SECRETS = os.path.join(BASE_DIR, 'rental/client_secrets.json') - flow = InstalledAppFlow.from_client_secrets_file(SECRETS, scopes=SCOPES, - redirect_uri="http://localhost:8080/") + flow = InstalledAppFlow.from_client_secrets_file( + SECRETS, scopes=SCOPES, redirect_uri="http://localhost:8080/") creds = flow.run_local_server() # Save the credentials for the next run with open('token.pickle', 'wb') as token: pickle.dump(creds, token) service = build('calendar', 'v3', credentials=creds) - calendar = place.name + calendars = { 'T2': "burik7aclvhc7vsboh06c179uo@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 - # for calendar in calendars: events_result = service.events().list( - calendarId=calendars[calendar], + calendarId=calendars[place.name], timeMin=now, singleEvents=True, orderBy='startTime' @@ -60,43 +63,52 @@ def synchronize_calendars(place): else: for event in events: reservation = { - 'place': calendar.strip(), + 'place': place.name.strip(), 'guest': event['summary'].strip(), 'start': event['start'].get('dateTime', event['start'].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']) - if not guest.exists(): - guest = Guest.objects.create(name=reservation['guest']) - else: - # guest = guest[0] - guest = guest.first() +def synchronize_calendars(place): + """ + Get a complete list of existing bookings in calendar + Creates reservation if not in db, update if already in db + Delete from db reservation deleted from cal + """ + reservation = get_calendar_reservations(place) - db_booking = Reservation.objects.filter( - guest=guest - ) + place = get_object_or_404(Place, name=place.name) + price = get_reservation_price( + place, reservation['start'], reservation['end']) + start = reservation['start'] + end = reservation['end'] - if not db_booking.exists(): - Reservation.objects.create( - place=place, - 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 + guest = Guest.objects.filter(name=reservation['guest']) + if not guest.exists(): + guest = Guest.objects.create(name=reservation['guest']) + else: + guest = guest.first() + + db_booking = Reservation.objects.filter( + guest=guest + ) + + if not db_booking.exists(): + Reservation.objects.create( + place=place, + 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): @@ -121,5 +133,15 @@ def check_availability(place, start_date, end_date): return True -if __name__ == '__main__': - synchronize_calendars() +def update_calendar(reservation): + """ 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 + ) diff --git a/rental/static/rental/lib/owlcarousel/LICENSE b/rental/static/rental/lib/owlcarousel/LICENSE deleted file mode 100644 index 052211d..0000000 --- a/rental/static/rental/lib/owlcarousel/LICENSE +++ /dev/null @@ -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. diff --git a/rental/views.py b/rental/views.py index a50f399..4b17f70 100644 --- a/rental/views.py +++ b/rental/views.py @@ -6,7 +6,7 @@ from django.views.generic.base import TemplateView from .forms import ReservationForm from django.db import IntegrityError 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 @@ -123,6 +123,7 @@ def reservation(request): end=end, price=price ) + update_calendar(reservation) context = { 'reservation': reservation }