sheet_name must always be present on a sheet row, but is only present on a db row
if the db actually stores that data.
As a side benefit, the db will now update if sheet_name changes.
This helps differentiate the multiple syncs we now have and will have:
- syncing events from streamlog
- reverse syncing events to sheets
- syncing playlists
This is a mode where all data flows one-way from the database to the sheet.
It is intended to be used to populate an empty sheet from database events,
possibly sourced from somewhere else.
To make this work, a few changes were required:
* Track which ids we've seen so we know what events were not matched with a row
* Allow `row` to be None in sync_rows
* When it is, call the middleware to create a new row with a new id
* In sheets, this is implemented by tracking the last empty rows we saw, and claiming them as needed.
NOTE ON CONFLICTS
In master, we moved sheets.py to common as it only contained a generic client.
Now sheets.py also contains specific sheetsync stuff.
Our resolution:
- Keep the generic version in common
- Keep the old version verbatim (including the now-redundant generic client) in sheetsync
We will move the sheetsync implementation to the generic client after the rebase is complete.
By restarting the update immediately instead of waiting for the next one.
We only try this up to 3 times to prevent excessive quota usage if it keeps happening.
Previously, we would only do reorderings if we were refreshing the playlist
for some other reason (eg. a video was inserted).
We want to refresh the playlist before attempting reorderings,
so we split the routine into two parts:
- A part that finds out-of-order videos and returns a list of moves to make.
- A part that executes those moves.
We do the former before AND after refreshing, and the latter only with the result from after.
In addition to sorting the videos themselves into the correct spots,
we need to special case them when scanning for the correct place to insert other videos.
Note this only places them in the correct place on insert,
which requires they be set in the playlist config BEFORE being inserted.
A follow-up commit will handle the case of needing to re-order them post insert.
And switch to passing around a namedtuple of these + tags instead of just tags.
To avoid confusion with the list of videos in the playlist, we refer to this data as the "playlist config".
These represent a pinned first/last video in a playlist.
On the choice of a video id vs an event id:
- Event ids are known before video ids, so we can "set and forget" before a video is uploaded
- No need to re-set if an event's video is re-edited or changed
- In cases where an external video is desired, we can use manual link to associate an event with it
Since we're referencing a primary key, we might as well also make it a proper foreign key
with sensible delete behaviour, though in practice we never delete events.
This is required in order to be able to move entries later.
Note our view of entry IDs may always be out of date, so any time you use one
you have to handle it no longer existing.