"""Equalize both DB's object collections; prefer newer states to older."""
id_name = 'id_' if 'id' == cls.id_name else cls.id_name
obj_colls = cls.get_all(dbs[0]), cls.get_all(dbs[1])
- for obj_0 in [obj for obj in obj_colls[0] if obj not in obj_colls[1]]:
+ for obj_0 in [obj for obj in obj_colls[0] # only pick objs without equal
+ if obj not in obj_colls[1]]: # in 2nd coll, even if same ID
id_ = getattr(obj_0, id_name)
sync_down = True
+ to_str = obj_0
msg_verb = 'adding'
- for obj_1 in [obj for obj in obj_colls[1] # other collection has …
- if id_ == getattr(obj, id_name)]: # … obj, but non-equal
+ direction = f'{host_names[1]}->{host_names[0]}'
+ for obj_1 in [obj for obj in obj_colls[1] # pick those from 2nd coll
+ if id_ == getattr(obj, id_name)]: # of same ID as obj_0
msg_verb = 'updating'
if hasattr(obj_0, ATTR_NAME_LAST_UPDATE):
last_update_0 = getattr(obj_0, ATTR_NAME_LAST_UPDATE)
last_update_1 = getattr(obj_1, ATTR_NAME_LAST_UPDATE)
sync_down = last_update_0 > last_update_1
if not sync_down:
- print(f'SYNC: {msg_verb} '
- f'{host_names[1]}->{host_names[0]} {id_}')
+ direction = f'{host_names[0]}->{host_names[1]}'
+ to_str = obj_1
obj_1.save(dbs[0])
if sync_down:
- print(f'SYNC: {msg_verb} {host_names[0]}->{host_names[1]} {id_}')
obj_0.save(dbs[1])
+ print(f'SYNC {cls.__name__}: {msg_verb} {direction} {id_} {to_str}')
def sync_relations(host_names: tuple[str, str],
"""To dbs[1] add YT yt_video->yt_q_colls[0] mapping not in yt_q_colls[1]"""
yt_q_colls = tuple(YoutubeQuery.get_all_for_video(db, yt_result.id_)
for db in dbs)
+ direction = f'adding {host_names[1]}->{host_names[0]} mapping'
+ result = f'result {yt_result.id_} ({yt_result})'
for q in [q for q in yt_q_colls[0] if q not in yt_q_colls[1]]:
- print(f'SYNC: adding {host_names[1]}->{host_names[0]} mapping '
- f'of result {yt_result.id_} to query {q.id_}')
+ print(f'SYNC: {direction} of query {q.id_} ({q}) to {result}')
yt_result.save_to_query(dbs[1], q.id_)
class YoutubeQuery(DbData):
"""Representation of YouTube query (without results)."""
_table_name = 'yt_queries'
+ _str_field = 'text'
_cols = ('id_', 'text', 'retrieved_at')
def __init__(self,
class YoutubeVideo(DbData):
"""Representation of YouTube video metadata as provided by their API."""
_table_name = 'yt_videos'
+ _str_field = 'title'
_cols = ('id_', 'title', 'description', 'published_at', 'duration',
'definition')
"""Collects data about downloaded files."""
id_name = 'digest'
_table_name = 'files'
+ _str_field = 'rel_path'
_cols = ('digest', 'rel_path', 'flags', 'yt_id', 'last_update', 'tags_str')
last_update: DatetimeStr
rel_path: Path
class QuotaLog(DbData):
"""Collects API access quota costs."""
_table_name = 'quota_costs'
+ _str_field = 'timestamp'
_cols = ('id_', 'timestamp', 'cost')
def __init__(self,