Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More
google
: Synchronize with Google¶
The lino_xl.lib.google
plugin adds functionality and database models to
synchronize calendar and contacts data between a Lino site and the
Google data of its users. See also the end-user documentation.
Side note: Code snippets (lines starting with >>>
) in this document get
tested as part of our development workflow. The following
initialization snippet tells you which demo project is being used in
this document.
>>> from lino import startup
>>> startup('lino_book.projects.noi1e.settings.demo')
>>> from lino.api.doctest import *
Overview¶
The site operator must define a web application with the People API and the Calendar API on the Google developer console.
More precisely it synchronizes three database models:
contacts.Person
cal.Entry
cal.Calendar
Plugin configuration¶
The following plugin attributes can be configured in the settings.py
.
- google.contacts_model¶
The database model used to represent a person on this site. If this is a
str
. Lino will resolve it into a database model during site startup.Default value is
'contacts.Person'
.
- google.application_name¶
The application’s name defined in the Google API Console
- google.num_retries¶
How many times to call GoogleAPI in case of
googleapiclient.errors.HttpError
- Type:
int
- Value:
3
- google.client_secret_file¶
JSON-formatted GoogleAPI client secret. To be obtained from Google.
If this is a
str
, Lino will convert it into apathlib.Path
during site startup.Default value is a file named
google_creds.json
in thesite_dir
.See How to get GoogleAPI credentials below.
- google.scopes¶
The list of scopes to which Lino will ask access to when connecting to the Google API.
- Type:
list
>>> pprint(dd.plugins.google.scopes) ['https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/contacts', 'https://www.googleapis.com/auth/calendar', 'https://www.googleapis.com/auth/calendar.events']
After modifying these scopes, delete all database entries for this auth provider and reauthenticate.
- google.entry_state_translation¶
Translate
EntryState
into google status.- Type:
tuple[tuple[str, tuple[str, …]]]
- Value:
((‘confirmed’, (‘confirmed’, )), (‘tentative’, (‘tentative’, )), (‘cancelled’, (‘cancelled’, )))
The first value of the inner tuples is the corresponding Google event status for the EntryState names in the second value (which is also a tuple).
- google.guest_state_translation¶
Translate between possible values in Google and Lino guest state choices.
- Type:
tuple[tuple[str, tuple[str, …]]
- Value:
((‘needsAction’, (‘needsAction’, )), (‘declined’, (‘decliend’, )), (‘tentative’, (‘tentative’, )), (‘accepted’, (‘accepted’, )))
Add more items on the second item of the inner toples so that they translate to the first item on the inner tuple.
Utilities¶
The plugin also provides a utility function:
Model mixins¶
- class lino_xl.lib.google.AccessLockable¶
A model mixin to lock access to the database object (on each database query), allowing only one transaction to such objects.
Inherits from
Modified
.On calling the save method. The object is unlocked automatically and should not be used at all afterwards. To use it further fetch it from the database again, and further access will be locked automatically.
This might be dangerous in case a locked instance is lost from a python session, and could be hard to get this object back from the database. Workarounds: Use the
unlock_all()
orunlock_objects()
to modify them at the database level. Or get a list of pk(s) usingget_locked_objects_pk()
and use_force_get()
instead. The following methods are available for troubleshooting:- classmethod unlock_all()¶
Unlocks all database objects.
- classmethod unlock_objects(pk_list: list)¶
Given a list of pk(s) it unlocks them at the database level.
- classmethod get_locked_objects_pk()¶
Returns a list of pk(s) of the currently locked objects.
- class lino_xl.lib.google.SyncToken¶
A model mixin inherits from
AccessLockable
andUserAuthored
.- sync_token¶
A CharField to store nextSyncToken retrieved from Google API call.
- page_token¶
A CharField to store nextPageToken retrieved from Google API call.
- class lino_xl.lib.google.GoogleSynchronized¶
Google’s related database models inherits from this mixin.
- google_id¶
Used in making reference to the object stored in Google’s database.
- class lino_xl.lib.google.GoogleCalendarSynchronized¶
A subclass of
GoogleSynchronized
.- modified¶
Keeps the timestamp of the last modification of the
Calendar
as an entry.- Type:
Helps in synchronization with Google.
- insert_or_update_into_google(self, resource, synchronizer) None ¶
Insert or updates the calendar entry with google.
- Parameters:
resource – Google calendar API resource. Can be obtained by calling Resource.calendars()
synchronizer – An instance of
Synchronizer
- classmethod get_outward_insert_update_queryset(cls, user)¶
This method returns a queryset of
Calendar
that are not stored in Google or should be updated.- Parameters:
user – An instance of
User
- Returns:
django.db.models.query.QuerySet
- classmethod delete_google_calendar(cls, cal: dict, synchronizer) None ¶
This method deletes a
Calendar
at sync time when the calendar is deleted from the Google calendar.- Parameters:
cal (dict) – Dictionary of attributes of the deleted calendar.
synchronizer – An instance of
Synchronizer
Also deletes the
DeletedEntry
record from the database to keep it clean.
- classmethod sync_deleted_records(cls, resource, synchronizer) None ¶
Deletes calendars by looking at
DeletedEntry
from Google calendar.- Parameters:
resource – Google calendar API resource. Can be obtained by calling Resource.calendars()
synchronizer – An instance of
Synchronizer
- classmethod insert_or_update_google_calendar(cls, cal: dict, synchronizer)¶
Inserts or updates a calendar entry and the default
Room
.- Parameters:
cls – A subclass of
GoogleCalendarSynchronized
.cal (dict) – A dictionary of calendar attibutes.
synchronizer – An instance of
Synchronizer
- Returns:
A tuple of the saved calendar entry and the default room.
- Return type:
- class lino_xl.lib.google.GoogleCalendarEventSynchronized¶
A subclass of
GoogleSynchronized
.- classmethod delete_google_event(cls, cal: dict, synchronizer) None ¶
This method deletes a
Event
at sync time when the event is deleted from the Google calendar.- Parameters:
event (dict) – Dictionary of attributes of the deleted event.
synchronizer – An instance of
Synchronizer
Also deletes the
DeletedEntry
record from the database to keep it clean.
- classmethod sync_deleted_records(cls, resource, synchronizer) None ¶
Deletes events by looking at
DeletedEntry
from Google calendar.- Parameters:
resource – Google calendar API resource. Can be obtained by calling Resource.events()
synchronizer – An instance of
Synchronizer
- classmethod get_outward_insert_update_queryset(cls, user)¶
This method yields
Event
(s) which are not stored in Google or should be updated.
- insert_or_update_into_google(self, resource, synchronizer) None ¶
Insert or updates the events into Google.
- Parameters:
resource – Google calendar API resource. Can be obtained by calling Resource.events()
synchronizer – An instance of
Synchronizer
- classmethod insert_or_update_google_event(cls, event: dict, room, synchronizer)¶
Inserts or updates a calendar entry and related
Room
andGuest
‘s.- Parameters:
cls – A subclass of
GoogleCalendarEventSynchronized
.room (
Room
.) – The room this event belongs to.synchronizer – An instance of
Synchronizer
- Returns:
Saved calendar event entry.
- Return type:
- class lino_xl.lib.google.GoogleContactSynchronized¶
A subclass of
GoogleSynchronized
.- classmethod delete_google_contact(cls, contact: dict, synchronizer) None ¶
This method deletes a
Contact
at sync time when the contact is deleted from Google.- Parameters:
contact (dict) – Dictionary of attributes of the deleted contact.
synchronizer – An instance of
Synchronizer
Also deletes the
DeletedContact
record from the database to keep it clean.
- classmethod sync_deleted_records(cls, resource, synchronizer) None ¶
Deletes contacts by looking at
DeletedContact
from Google.- Parameters:
resource – Google people API resource. Can be obtained by calling Resource.people()
synchronizer – An instance of
Synchronizer
- classmethod get_outward_insert_update_queryset(cls, user: users.User = None)¶
Returns contacts insertable or updatable into Google.
- Parameters:
user – An instance of
User
- Returns:
django.db.models.QuerySet
- insert_or_update_into_google(self, resource, synchronizer)¶
Insert or updates the contact into Google.
- Parameters:
resource – Google people API resource. Can be obtained by calling Resource.people()
synchronizer – An instance of
Synchronizer
Choices and choicelists¶
Defines ChoiceList(s) and some utility functions.
- lino_xl.lib.google.google_status(state: EntryState | GuestState) str | None ¶
- Parameters:
state – Takes either a
EntryState
or aGuestState
.- Returns:
An str as status acceptable by Google.
Internally it works by looking at state_translation either
google.entry_state_translation
when the input parameter is an instance of anEntryState
orgoogle.guest_state_translation
when the input parameter is an instance of aGuestState
. It returns None if a value is not found for a corresponding state.>>> google.google_status(cal.EntryStates.tentative) 'tentative'
- class lino_xl.lib.google.AccessRoles¶
Keeps the choices for the type of access to a Google calendar.
Used for checking whether a user can insert into a Google calendar. The available values are
freeBusyReader
(read public info only),reader
,writer
andowner
.>>> rt.show(google.AccessRoles) ======= ================ ================== value name text ------- ---------------- ------------------ p freeBusyReader Free busy reader r reader Reader w writer Writer o owner Owner ======= ================ ==================
Database objects¶
- class lino_xl.lib.google.CalendarSubscription¶
A subclass of
BaseSubscription
.- primary¶
A boolean field which indicated whether calendar referenced in this subscription is the primary calendar for the user in Google.
- access_role¶
User’s access role on the subscribed calendar.
See:
AccessRoles
- class lino_xl.lib.google.EventSyncToken¶
A subclass of
SyncToken
, stores necessary tokens to sync the events updated in a user’s google calendar.- subscription¶
A ForeignKey pointing to a
CalendarSubscription
object.
- class lino_xl.lib.google.CalendarSyncToken¶
A subclass of
SyncToken
, store the necessary tokens to sync the calendars updated on a user’s google account.
- class lino_xl.lib.google.DeletedEntry¶
Keeps a record of the natively deleted
Calendar
orEvent
for deleting from Google when the next sync is run.- calendar¶
A boolean field which says whether the deleted item is a Calendar if not it is an Event.
- Type:
- Value:
False
- event_id¶
Takes the value of the
Event.google_id
when the deleted record is anEvent
otherwise an empty string.- Type:
- calendar_id¶
Takes the value of the
Calendar.google_id
- Type:
If the deleted record is an Event it takes the google_id from the Calendar in which the deleted Event belongs to.
- class lino_xl.lib.google.Contact¶
Keeps a reference to a google contact.
A subclass of
UserAuthored
,GoogleContactSynchronized
andModified
.- contact¶
A ForeignKey pointing to
google.contacts_model
.
- class lino_xl.lib.google.DeletedContact¶
Keeps meta information of a deleted contact to sync with google upon next synchronization.
A subclass of
UserAuthored
.- contact_id¶
The google resourceName.
- class lino_xl.lib.google.ContactSyncToken¶
Stores the nextSyncToken and nextPageToken from google.
A subclass of
SyncToken
.
- class lino_xl.lib.google.SyncSummary¶
Database model to store the summaries of a
Synchronizer.sync()
session.Subclass of
UserAuthored
andCreated
- halted¶
A BooleanField indicate whether the sync session has failed.
- stats¶
A TextField containing the textual representation of synchronization session statistics.
- class lino_xl.lib.google.FailedForeignItem¶
Database model to store the foreign objects failed to put into the local database.
- job¶
A ForeignKey pointing to the corresponding
SyncSummary
.
- value¶
A JSONField containing the actual remote object.
- item_class¶
A ForeignKey pointing to the related database model (contenttypes.ContentType) specifying the item synchronization class.
Interaction with other plugins¶
This plugin adds the following method get_country
to
lino.modlib.users.User
model:
- class lino.modlib.users.User
- get_contact()¶
Returns the user’s country.
Synchronization¶
Calendar and contacts synchronization in Lino with Google works in both ways. Lino application can fetch entries from Google as well as it can insert and update entries into Google.
By default google.contacts_model
are not synchronisable with google
unless they pointed to by some Contact
instance.
- class lino_xl.lib.google.FailedEntries¶
A subclass of typing.NamedTuple. And has the following attributes.
- calendars¶
Contains reference to the
Calendar
instance(s) that failed to sync with Google.- Type:
list[django.db.models.QuerySet]
- Value:
[]
- events¶
Contains reference to the
Event
instance(s) that failed to sync with Google.- Type:
- Value:
[]
- class lino_xl.lib.google.Synchronizer¶
The class that wraps the synchronization functionality.
- _failed_entries¶
Keeps reference to the database objects that failed to sync with google from the last
sync()
call.- Type:
- failed_entries¶
Keeps reference to the database objects that failed to sync with google in the running
sync()
call.- Type:
- sync() self ¶
Synchronizes latest changes with Google.
How to get GoogleAPI credentials¶
Log in to your Google Developer Console.
Create a project in the console if you don’t have one already.
In the Google console, navigate to
and thenclick on + ENABLE APIS AND SERVICES
search for Google People API and enable this API
search for Google Calendar API and enable this API
For detailed information follow this Google API Console Help page.
Navigate to
thenclick on
choose OAuth client ID.
Set the Application type to Web application.
In the Authorized redirect URIs section click on + ADD URI and put your matching URI to the following regex and hit CREATE:
>>> your_server_host_name = r".*" >>> uri_pattern = r"^http(s)?://" + your_server_host_name + r"/oauth/complete/google/$"
Click on the DOWNLOAD JSON button to download the credentials. Save
them as a file named google_creds.json
in the site_dir
.
You can also store them in a different place and specify the file’s full path
name in google.client_secret_file
in your settings.py
:
class Site(...):
...
def get_plugin_configs(self):
...
yield 'google', 'client_secret_file', '/path/to/my/credentials.json'
...
Navigate to
and put the email addresses of some test users.And that’s almost it for getting Google API credentials.
Otherwise see this thread.