diff --git a/.gitignore b/.gitignore index cf78c5b..e6cc0a8 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,6 @@ rental/static/ Procfile heroku.yml rental/client_secrets.json - +calendar.dat +token.pickle +villafleurie.pgsql \ No newline at end of file diff --git a/README.md b/README.md index 92495ff..e6da59f 100644 --- a/README.md +++ b/README.md @@ -96,3 +96,5 @@ Le visiteur doit pouvoir : \_ nettoyer les statics files. Garder que les définitions utiles ## BUGS + +- La synchro ne gère pas les heures dans le calendriers. diff --git a/rental/bookings.py b/rental/bookings.py index 73e2593..ab4e301 100644 --- a/rental/bookings.py +++ b/rental/bookings.py @@ -1,13 +1,14 @@ import datetime from rental.pricing import get_reservation_price from django.shortcuts import get_object_or_404 -from rental.models import Reservation, Place +from rental.models import Reservation, Place, Guest import datetime from google.auth.transport.requests import Request from google_auth_oauthlib.flow import InstalledAppFlow from googleapiclient.discovery import build import os.path import pickle +from villafleurie.settings import BASE_DIR def get_bookings(place): @@ -49,8 +50,9 @@ def synchronize_calendars(): if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: - flow = InstalledAppFlow.from_client_secrets_file( - 'client_secrets.json', scopes=SCOPES, redirect_uri="http://localhost:8080/") + SECRETS = os.path.join(BASE_DIR, 'rental/client_secrets.json') + 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: @@ -74,32 +76,38 @@ def synchronize_calendars(): if not events: print('No upcoming events found.') else: - reservation = {} - for index, event in enumerate(events): - reservation[index] = { + # reservation = {} + for event in events: + reservation = { 'place': calendar, 'guest': event['summary'], 'start': event['start'].get('dateTime', event['start'].get('date')), 'end': event['end'].get('dateTime', event['end'].get('date')) } - print(reservation[index]) + print(reservation) # if booking not in db -> create # if booking in db and modification_date_cal > update_date_db -> update - - place = get_object_or_404(Place, name=calendar) - price = get_reservation_price( - place, reservation['start'], reservation['end']) - # trouver si guest existe déjà, créer sinon - guest = Guest.objects.create(name=reservation['guest']) - - Reservation.objects.create( - place=place, - guest=guest, - start=start, - end=end, - price=price - ) +# try : create/update +# except : send a log message + try: + place = get_object_or_404(Place, name=calendar) + price = get_reservation_price( + place, reservation['start'], reservation['end']) + # trouver si guest existe déjà, créer sinon + guest = Guest.objects.create(name=reservation['guest']) + start = reservation['start'] + end = reservation['end'] + Reservation.objects.create( + place=place, + guest=guest, + start=start, + end=end, + price=price + ) + except: + print( + f"######## ERROR ! Can't create {guest} reservation ########") if __name__ == '__main__': diff --git a/rental/models.py b/rental/models.py index 29dc4b2..d2b983f 100644 --- a/rental/models.py +++ b/rental/models.py @@ -39,7 +39,7 @@ class Guest(models.Model): return self.name name = models.CharField(max_length=100) - email = models.EmailField(unique=True) + email = models.EmailField(unique=False) phone = models.CharField(max_length=30, blank=True) diff --git a/rental/pricing.py b/rental/pricing.py index 3b98d8a..019e346 100644 --- a/rental/pricing.py +++ b/rental/pricing.py @@ -1,14 +1,20 @@ +from datetime import datetime + + def get_reservation_price(place, start, end): """ Compute booking price as a function of place and dates """ + start = datetime.strptime(start, '%Y-%m-%d') + end = datetime.strptime(end, '%Y-%m-%d') + nights = (end - start).days return place.price * nights if __name__ == '__main__': from rental.models import Place - from datetime import * + from datetime import datetime from django.shortcuts import get_object_or_404 place_name = 'T2' place = get_object_or_404(Place, name=place_name) diff --git a/rental/views.py b/rental/views.py index b74fb98..e29f9f0 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 # import sys @@ -143,6 +143,7 @@ def calendar(request, place_name): """ returns a list of all related place reservations """ + synchronize_calendars() booked_dates = Reservation.objects.all() bookings = [ booking for booking in booked_dates if booking.place.name == place_name] diff --git a/villafleurie.json b/villafleurie.json index b35bcef..2ed60be 100644 --- a/villafleurie.json +++ b/villafleurie.json @@ -121,10 +121,10 @@ }, { "model": "sessions.session", - "pk": "pe2dvr7dfkqagrcs2trec5aj7ep57rvz", + "pk": "v9w10z63mcilrzwa1asqd6fq4sdhoula", "fields": { - "session_data": "OTc5Y2U3Zjc1YWQzOTAxNjA0MjQ1NTI3MDk0NTkxYjlmM2YyNDMxNDp7Il9hdXRoX3VzZXJfaWQiOiIyIiwiX2F1dGhfdXNlcl9iYWNrZW5kIjoiZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmQiLCJfYXV0aF91c2VyX2hhc2giOiJjMjE1MTliMGU3ODIwYTkwMjIzNjIwZjE3MWU0MmM1ZGFhZGE3YjBiIn0=", - "expire_date": "2019-12-18T13:11:01.964Z" + "session_data": "NzhmMTE3YWExMjExY2FjZDI4NDI4MmQxNDI1MjQwYzViZjczM2Q3Mjp7Il9hdXRoX3VzZXJfaWQiOiIyIiwiX2F1dGhfdXNlcl9iYWNrZW5kIjoiZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmQiLCJfYXV0aF91c2VyX2hhc2giOiI1NTkwY2NlZjM1YzFhNDhiNjE4ZGJiNWI3YjZkZWUwZjFmYjU0NjYyIn0=", + "expire_date": "2019-12-23T17:27:03.312Z" } }, { @@ -221,6 +221,7 @@ "beds": 1, "max_occupation": 2, "thumbnail": 1, + "calendar": "https://calendar.google.com/calendar/embed?height=600&wkst=2&bgcolor=%23ffffff&ctz=America%2FMartinique&src=YnVyaWs3YWNsdmhjN3ZzYm9oMDZjMTc5dW9AZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&color=%23DD4477&showTitle=0&showCalendars=0&showTabs=1&showPrint=0&showDate=1&showNav=1", "images": [ 7, 6, @@ -246,6 +247,7 @@ "beds": 2, "max_occupation": 4, "thumbnail": 10, + "calendar": "https://calendar.google.com/calendar/embed?height=600&wkst=2&bgcolor=%23ffffff&ctz=America%2FMartinique&showTitle=0&showCalendars=0&showTabs=1&showPrint=0&showDate=1&showNav=1&src=ZnU3aDMwcDBnazRhMnA0bnZvN25zYmdwb2tAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ&color=%233366CC", "images": [ 7, 6, @@ -760,15 +762,23 @@ "codename": "view_image" } }, + { + "model": "auth.group", + "pk": 1, + "fields": { + "name": "Clients", + "permissions": [] + } + }, { "model": "auth.user", "pk": 1, "fields": { "password": "pbkdf2_sha256$150000$FUvMBlxIZy6y$HmwSAxQAdPaOve3XwCYfDx/3Oklh2WtG2QJewPcrO+s=", - "last_login": "2019-12-03T12:22:52.850Z", + "last_login": "2019-12-03T12:22:52Z", "is_superuser": true, "username": "admin", - "first_name": "Ruidy", + "first_name": "Nilka", "last_name": "Nemausat", "email": "location.villafleurie@gmail.com", "is_staff": true, @@ -780,6 +790,10 @@ 26, 27, 28, + 49, + 50, + 51, + 52, 29, 30, 31, @@ -799,18 +813,71 @@ "model": "auth.user", "pk": 2, "fields": { - "password": "pbkdf2_sha256$150000$Bm05RbDiL5KK$ok0/kUpbommwOCOo6TeY4De7mVSrOnONdmdN2fvWFV4=", - "last_login": "2019-12-04T13:11:01.941Z", + "password": "pbkdf2_sha256$180000$0vN9vhsYeNft$6ema2p7l0l6muwDnPcpNO6dxJQc4qG7hIoyvzcBBAXc=", + "last_login": "2019-12-09T17:27:30Z", "is_superuser": true, "username": "ruidy", - "first_name": "", - "last_name": "", + "first_name": "Ruidy", + "last_name": "NEMAUSAT", "email": "ruidy.nemausat@gmail.com", "is_staff": true, "is_active": true, - "date_joined": "2019-12-04T13:10:55.470Z", + "date_joined": "2019-12-04T13:10:55Z", "groups": [], - "user_permissions": [] + "user_permissions": [ + 1, + 2, + 3, + 4, + 9, + 10, + 11, + 12, + 5, + 6, + 7, + 8, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 45, + 46, + 47, + 48, + 25, + 26, + 27, + 28, + 49, + 50, + 51, + 52, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 21, + 22, + 23, + 24, + 41, + 42, + 43, + 44 + ] } }, { @@ -2112,5 +2179,161 @@ "action_flag": 3, "change_message": "" } + }, + { + "model": "admin.logentry", + "pk": 101, + "fields": { + "action_time": "2019-12-06T12:17:40.493Z", + "user": 2, + "content_type": 8, + "object_id": "1", + "object_repr": "T2", + "action_flag": 2, + "change_message": "[{\"changed\": {\"fields\": [\"Calendar\"]}}]" + } + }, + { + "model": "admin.logentry", + "pk": 102, + "fields": { + "action_time": "2019-12-06T12:18:15.553Z", + "user": 2, + "content_type": 8, + "object_id": "2", + "object_repr": "T3", + "action_flag": 2, + "change_message": "[{\"changed\": {\"fields\": [\"Calendar\"]}}]" + } + }, + { + "model": "admin.logentry", + "pk": 103, + "fields": { + "action_time": "2019-12-06T12:19:44.349Z", + "user": 2, + "content_type": 8, + "object_id": "2", + "object_repr": "T3", + "action_flag": 2, + "change_message": "[]" + } + }, + { + "model": "admin.logentry", + "pk": 104, + "fields": { + "action_time": "2019-12-06T12:27:10.747Z", + "user": 2, + "content_type": 8, + "object_id": "1", + "object_repr": "T2", + "action_flag": 2, + "change_message": "[]" + } + }, + { + "model": "admin.logentry", + "pk": 105, + "fields": { + "action_time": "2019-12-06T12:27:35.355Z", + "user": 2, + "content_type": 8, + "object_id": "2", + "object_repr": "T3", + "action_flag": 2, + "change_message": "[]" + } + }, + { + "model": "admin.logentry", + "pk": 106, + "fields": { + "action_time": "2019-12-09T17:27:42.217Z", + "user": 2, + "content_type": 4, + "object_id": "2", + "object_repr": "ruidy", + "action_flag": 2, + "change_message": "[{\"changed\": {\"fields\": [\"First name\", \"Last name\", \"User permissions\", \"Last login\"]}}]" + } + }, + { + "model": "admin.logentry", + "pk": 107, + "fields": { + "action_time": "2019-12-09T17:28:38.006Z", + "user": 2, + "content_type": 4, + "object_id": "1", + "object_repr": "admin", + "action_flag": 2, + "change_message": "[{\"changed\": {\"fields\": [\"First name\", \"User permissions\"]}}]" + } + }, + { + "model": "admin.logentry", + "pk": 108, + "fields": { + "action_time": "2019-12-09T17:29:31.434Z", + "user": 2, + "content_type": 3, + "object_id": "1", + "object_repr": "Clients", + "action_flag": 1, + "change_message": "[{\"added\": {}}]" + } + }, + { + "model": "admin.logentry", + "pk": 109, + "fields": { + "action_time": "2019-12-09T17:30:49.765Z", + "user": 2, + "content_type": 7, + "object_id": "40", + "object_repr": "Thomas Price", + "action_flag": 3, + "change_message": "" + } + }, + { + "model": "admin.logentry", + "pk": 110, + "fields": { + "action_time": "2019-12-09T17:30:49.768Z", + "user": 2, + "content_type": 7, + "object_id": "39", + "object_repr": "John Doe", + "action_flag": 3, + "change_message": "" + } + }, + { + "model": "admin.logentry", + "pk": 111, + "fields": { + "action_time": "2019-12-09T17:30:49.769Z", + "user": 2, + "content_type": 7, + "object_id": "38", + "object_repr": "Nilka", + "action_flag": 3, + "change_message": "" + } + }, + { + "model": "admin.logentry", + "pk": 112, + "fields": { + "action_time": "2019-12-09T17:30:49.771Z", + "user": 2, + "content_type": 7, + "object_id": "37", + "object_repr": "NEMAUSAT Ruidy", + "action_flag": 3, + "change_message": "" + } } ] \ No newline at end of file