mirror of
https://github.com/TurTaskProject/TurTaskWeb.git
synced 2025-12-18 21:44:07 +01:00
Improve Google API Sync
This commit is contained in:
parent
fcf674f3f6
commit
c926a9f332
@ -164,10 +164,12 @@ DATABASES = {
|
|||||||
|
|
||||||
# Cache
|
# Cache
|
||||||
|
|
||||||
|
CACHES_LOCATION = f"{config('DB_NAME', default='db_test')}_cache"
|
||||||
|
|
||||||
CACHES = {
|
CACHES = {
|
||||||
"default": {
|
"default": {
|
||||||
"BACKEND": "django.core.cache.backends.db.DatabaseCache",
|
"BACKEND": "django.core.cache.backends.db.DatabaseCache",
|
||||||
"LOCATION": "dbtest",
|
"LOCATION": CACHES_LOCATION,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,24 +1,68 @@
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from rest_framework import viewsets
|
from rest_framework import viewsets
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.permissions import IsAuthenticated, AllowAny
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
|
||||||
from googleapiclient.discovery import build
|
from tasks.utils import get_service
|
||||||
|
from tasks.models import Task
|
||||||
from .serializers import GoogleCalendarEventSerializer
|
from tasks.serializers import TaskUpdateSerializer
|
||||||
from users.access_token_cache import get_credential_from_cache_token
|
|
||||||
|
|
||||||
|
|
||||||
class GoogleCalendarEventViewset(viewsets.ViewSet):
|
class GoogleCalendarEventViewset(viewsets.ViewSet):
|
||||||
permission_classes = (IsAuthenticated,)
|
permission_classes = (IsAuthenticated,)
|
||||||
|
|
||||||
def list(self, request, days=7):
|
def __init__(self, *args, **kwargs):
|
||||||
current_time = datetime.now(tz=timezone.utc).isoformat()
|
super().__init__()
|
||||||
max_time = (datetime.now(tz=timezone.utc) + timedelta(days=days)).isoformat()
|
self.current_time = datetime.now(tz=timezone.utc).isoformat()
|
||||||
credentials = get_credential_from_cache_token(request.user.id)
|
self.event_fields = 'items(id,summary,description,created,updated,start,end)'
|
||||||
service = build('calendar', 'v3', credentials=credentials)
|
|
||||||
events = service.events().list(calendarId='primary', timeMin=current_time, timeMax=max_time).execute()
|
|
||||||
|
|
||||||
return Response(events.get('items', []), status=200)
|
def _validate_serializer(self, serializer):
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
return Response("Task Sync Successfully", status=200)
|
||||||
|
return Response(serializer.errors, status=400)
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
service = get_service(request)
|
||||||
|
events = service.events().list(calendarId='primary', fields=self.event_fields).execute()
|
||||||
|
for event in events.get('items', []):
|
||||||
|
try:
|
||||||
|
task = Task.objects.get(google_calendar_id=event['id'])
|
||||||
|
serializer = TaskUpdateSerializer(instance=task, data=event)
|
||||||
|
return self._validate_serializer(serializer)
|
||||||
|
except Task.DoesNotExist:
|
||||||
|
serializer = TaskUpdateSerializer(data=event, user=request.user)
|
||||||
|
return self._validate_serializer(serializer)
|
||||||
|
|
||||||
|
def list(self, request, days=7):
|
||||||
|
max_time = (datetime.now(tz=timezone.utc) + timedelta(days=3)).isoformat()
|
||||||
|
|
||||||
|
service = get_service(request)
|
||||||
|
events = []
|
||||||
|
next_page_token = None
|
||||||
|
|
||||||
|
while True:
|
||||||
|
query = service.events().list(
|
||||||
|
calendarId='primary',
|
||||||
|
timeMin=self.current_time,
|
||||||
|
timeMax=max_time,
|
||||||
|
maxResults=20,
|
||||||
|
singleEvents=True,
|
||||||
|
orderBy='startTime',
|
||||||
|
pageToken=next_page_token,
|
||||||
|
fields='items(id,summary,description,created,updated,start,end)',
|
||||||
|
)
|
||||||
|
|
||||||
|
page_results = query.execute()
|
||||||
|
page_events = page_results.get('items', [])
|
||||||
|
|
||||||
|
events.extend(page_events)
|
||||||
|
next_page_token = page_results.get('nextPageToken')
|
||||||
|
|
||||||
|
if next_page_token is None:
|
||||||
|
break
|
||||||
|
|
||||||
|
return Response(events, status=200)
|
||||||
@ -14,16 +14,6 @@ class Migration(migrations.Migration):
|
|||||||
model_name='task',
|
model_name='task',
|
||||||
name='reminders',
|
name='reminders',
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
|
||||||
model_name='task',
|
|
||||||
name='end_event',
|
|
||||||
field=models.DateTimeField(blank=True, null=True),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='task',
|
|
||||||
name='start_event',
|
|
||||||
field=models.DateTimeField(blank=True, null=True),
|
|
||||||
),
|
|
||||||
migrations.DeleteModel(
|
migrations.DeleteModel(
|
||||||
name='Reminder',
|
name='Reminder',
|
||||||
),
|
),
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 4.2.6 on 2023-11-03 17:43
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('tasks', '0007_remove_task_reminders_task_end_event_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='task',
|
||||||
|
name='end_event',
|
||||||
|
field=models.DateTimeField(null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='task',
|
||||||
|
name='start_event',
|
||||||
|
field=models.DateTimeField(null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -1,7 +1,7 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core import validators
|
from django.core import validators
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
class Tag(models.Model):
|
class Tag(models.Model):
|
||||||
"""
|
"""
|
||||||
@ -70,8 +70,8 @@ class Task(models.Model):
|
|||||||
creation_date = models.DateTimeField(auto_now_add=True)
|
creation_date = models.DateTimeField(auto_now_add=True)
|
||||||
last_update = models.DateTimeField(auto_now=True)
|
last_update = models.DateTimeField(auto_now=True)
|
||||||
google_calendar_id = models.CharField(blank=True, null=True, max_length=255)
|
google_calendar_id = models.CharField(blank=True, null=True, max_length=255)
|
||||||
start_event = models.DateTimeField(blank=True, null=True)
|
start_event = models.DateTimeField(null=True)
|
||||||
end_event = models.DateTimeField(blank=True, null=True)
|
end_event = models.DateTimeField(null=True)
|
||||||
|
|
||||||
|
|
||||||
class Subtask(models.Model):
|
class Subtask(models.Model):
|
||||||
|
|||||||
@ -1,8 +1,36 @@
|
|||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
from django.utils.dateparse import parse_datetime
|
||||||
|
from .models import Task
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
class GoogleCalendarEventSerializer(serializers.Serializer):
|
class GoogleCalendarEventSerializer(serializers.Serializer):
|
||||||
summary = serializers.CharField()
|
summary = serializers.CharField()
|
||||||
start = serializers.DateTimeField()
|
start = serializers.DateTimeField()
|
||||||
end = serializers.DateTimeField()
|
end = serializers.DateTimeField()
|
||||||
description = serializers.CharField(required=False)
|
description = serializers.CharField(required=False)
|
||||||
|
|
||||||
|
|
||||||
|
class TaskUpdateSerializer(serializers.ModelSerializer):
|
||||||
|
id = serializers.CharField(source="google_calendar_id")
|
||||||
|
summary = serializers.CharField(source="title")
|
||||||
|
description = serializers.CharField(source="notes", required=False)
|
||||||
|
created = serializers.DateTimeField(source="creation_date")
|
||||||
|
updated = serializers.DateTimeField(source="last_update")
|
||||||
|
start_datetime = serializers.DateTimeField(source="start_event", required=False)
|
||||||
|
end_datetime = serializers.DateTimeField(source="end_event", required=False)
|
||||||
|
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Task
|
||||||
|
fields = ('id', 'summary', 'description', 'created', 'updated', 'start_datetime', 'end_datetime')
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.user = kwargs.pop('user', None)
|
||||||
|
super(TaskUpdateSerializer, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
validated_data['user'] = self.user
|
||||||
|
task = Task.objects.create(**validated_data)
|
||||||
|
|
||||||
|
return task
|
||||||
56
backend/tasks/tests/test_deserializer.py
Normal file
56
backend/tasks/tests/test_deserializer.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from tasks.tests.utils import create_test_user, login_user
|
||||||
|
from tasks.serializers import TaskUpdateSerializer
|
||||||
|
from tasks.models import Task
|
||||||
|
|
||||||
|
class TaskUpdateSerializerTest(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.user = create_test_user()
|
||||||
|
self.current_time = '2020-08-01T00:00:00Z'
|
||||||
|
self.end_time = '2020-08-01T00:00:00Z'
|
||||||
|
|
||||||
|
def test_serializer_create(self):
|
||||||
|
data = {
|
||||||
|
'id': '32141cwaNcapufh8jq2conw',
|
||||||
|
'summary': 'Updated Task',
|
||||||
|
'description': 'Updated description',
|
||||||
|
'created': self.current_time,
|
||||||
|
'updated': self.end_time,
|
||||||
|
'start_datetime' : self.current_time,
|
||||||
|
'end_datetie': self.end_time,
|
||||||
|
}
|
||||||
|
|
||||||
|
serializer = TaskUpdateSerializer(data=data, user=self.user)
|
||||||
|
self.assertTrue(serializer.is_valid())
|
||||||
|
serializer.is_valid()
|
||||||
|
task = serializer.save()
|
||||||
|
self.assertIsInstance(task, Task)
|
||||||
|
|
||||||
|
def test_serializer_update(self):
|
||||||
|
task = Task.objects.create(title='Original Task', notes='Original description', user=self.user)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'id': '32141cwaNcapufh8jq2conw',
|
||||||
|
'summary': 'Updated Task',
|
||||||
|
'description': 'Updated description',
|
||||||
|
'created': self.current_time,
|
||||||
|
'updated': self.end_time,
|
||||||
|
'start_datetime' : self.current_time,
|
||||||
|
'end_datetie': self.end_time,
|
||||||
|
}
|
||||||
|
|
||||||
|
serializer = TaskUpdateSerializer(instance=task, data=data)
|
||||||
|
self.assertTrue(serializer.is_valid())
|
||||||
|
updated_task = serializer.save()
|
||||||
|
|
||||||
|
self.assertEqual(updated_task.title, 'Updated Task')
|
||||||
|
self.assertEqual(updated_task.notes, 'Updated description')
|
||||||
|
self.assertEqual(updated_task.start_event,
|
||||||
|
datetime.strptime(self.current_time,
|
||||||
|
'%Y-%m-%dT%H:%M:%SZ')
|
||||||
|
.replace(tzinfo=ZoneInfo(key='UTC')))
|
||||||
8
backend/tasks/utils.py
Normal file
8
backend/tasks/utils.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from googleapiclient.discovery import build
|
||||||
|
|
||||||
|
from users.access_token_cache import get_credential_from_cache_token
|
||||||
|
|
||||||
|
|
||||||
|
def get_service(request):
|
||||||
|
credentials = get_credential_from_cache_token(request.user.id)
|
||||||
|
return build('calendar', 'v3', credentials=credentials)
|
||||||
Loading…
Reference in New Issue
Block a user