Improve Google API Sync

This commit is contained in:
sosokker 2023-11-04 03:30:21 +07:00
parent fcf674f3f6
commit c926a9f332
8 changed files with 178 additions and 27 deletions

View File

@ -164,10 +164,12 @@ DATABASES = {
# Cache
CACHES_LOCATION = f"{config('DB_NAME', default='db_test')}_cache"
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.db.DatabaseCache",
"LOCATION": "dbtest",
"LOCATION": CACHES_LOCATION,
}
}

View File

@ -1,24 +1,68 @@
from datetime import datetime, timedelta
from django.utils import timezone
from rest_framework import viewsets
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 .serializers import GoogleCalendarEventSerializer
from users.access_token_cache import get_credential_from_cache_token
from tasks.utils import get_service
from tasks.models import Task
from tasks.serializers import TaskUpdateSerializer
class GoogleCalendarEventViewset(viewsets.ViewSet):
permission_classes = (IsAuthenticated,)
def list(self, request, days=7):
current_time = datetime.now(tz=timezone.utc).isoformat()
max_time = (datetime.now(tz=timezone.utc) + timedelta(days=days)).isoformat()
credentials = get_credential_from_cache_token(request.user.id)
service = build('calendar', 'v3', credentials=credentials)
events = service.events().list(calendarId='primary', timeMin=current_time, timeMax=max_time).execute()
def __init__(self, *args, **kwargs):
super().__init__()
self.current_time = datetime.now(tz=timezone.utc).isoformat()
self.event_fields = 'items(id,summary,description,created,updated,start,end)'
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)

View File

@ -14,16 +14,6 @@ class Migration(migrations.Migration):
model_name='task',
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(
name='Reminder',
),

View File

@ -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),
),
]

View File

@ -1,7 +1,7 @@
from django.db import models
from django.conf import settings
from django.core import validators
from django.utils import timezone
class Tag(models.Model):
"""
@ -70,8 +70,8 @@ class Task(models.Model):
creation_date = models.DateTimeField(auto_now_add=True)
last_update = models.DateTimeField(auto_now=True)
google_calendar_id = models.CharField(blank=True, null=True, max_length=255)
start_event = models.DateTimeField(blank=True, null=True)
end_event = models.DateTimeField(blank=True, null=True)
start_event = models.DateTimeField(null=True)
end_event = models.DateTimeField(null=True)
class Subtask(models.Model):

View File

@ -1,8 +1,36 @@
from rest_framework import serializers
from django.utils.dateparse import parse_datetime
from .models import Task
from datetime import datetime
class GoogleCalendarEventSerializer(serializers.Serializer):
summary = serializers.CharField()
start = 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

View 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
View 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)