refactor(quota): canonical <entity>_<action> taxonomy for quota events
The quota-attribution action keys were inconsistent (mixed verbs, ad-hoc names, English-only labels). Introduce a QuotaAction constants holder (one source of truth), rename every attribution call site to it, and add migration 0020 to rename historical quota_events.action values. The display label now resolves from i18n (quotaActions.<key>, EN/HU/DE) instead of a hard-coded English map. Scheduler job ids and progress phase labels are a separate namespace and are left untouched.
This commit is contained in:
parent
1ce035ca9e
commit
b23f805533
12 changed files with 151 additions and 33 deletions
|
|
@ -166,7 +166,7 @@ def discover_channels(
|
|||
# to yourself. Lazy + cached; needs OAuth, so demo / token-less users just skip it.
|
||||
if user.yt_channel_id is None and user.token is not None and not user.is_demo:
|
||||
try:
|
||||
with quota.attribute(user.id, "discovery"), YouTubeClient(db, user) as yt:
|
||||
with quota.attribute(user.id, quota.QuotaAction.CHANNELS_DISCOVER), YouTubeClient(db, user) as yt:
|
||||
own = yt.get_my_channel_id()
|
||||
if own:
|
||||
user.yt_channel_id = own
|
||||
|
|
@ -181,7 +181,7 @@ def discover_channels(
|
|||
need = [ch.id for ch, _, _ in rows if ch.details_synced_at is None][:DISCOVERY_ENRICH_CAP]
|
||||
if need:
|
||||
try:
|
||||
with quota.attribute(user.id, "discovery"), YouTubeClient(db, user) as yt:
|
||||
with quota.attribute(user.id, quota.QuotaAction.CHANNELS_DISCOVER), YouTubeClient(db, user) as yt:
|
||||
apply_channel_details(db, yt.get_channels(need))
|
||||
db.commit()
|
||||
rows = _discovery_rows(db, user)
|
||||
|
|
@ -243,7 +243,7 @@ def update_channel(
|
|||
# fetched its recent uploads yet, do that one channel now (cheap) instead of waiting for
|
||||
# the scheduler. Deep paging still follows on the scheduler's next run (recent-then-deep).
|
||||
if deep_turned_on and channel is not None and channel.recent_synced_at is None:
|
||||
with quota.attribute(user.id, "backfill_recent"):
|
||||
with quota.attribute(user.id, quota.QuotaAction.VIDEOS_BACKFILL_RECENT):
|
||||
run_recent_backfill(db, [channel], max_channels=1)
|
||||
|
||||
return {
|
||||
|
|
@ -274,7 +274,7 @@ def reset_backfill(
|
|||
channel.recent_synced_at = None
|
||||
sub.deep_requested = True
|
||||
db.commit()
|
||||
with quota.attribute(user.id, "backfill_recent"):
|
||||
with quota.attribute(user.id, quota.QuotaAction.VIDEOS_BACKFILL_RECENT):
|
||||
run_recent_backfill(db, [channel], max_channels=1)
|
||||
return {"id": channel_id, "reset": True}
|
||||
|
||||
|
|
@ -306,7 +306,7 @@ def subscribe(
|
|||
if existing is not None:
|
||||
raise HTTPException(status_code=409, detail="Already subscribed to this channel.")
|
||||
try:
|
||||
with quota.attribute(user.id, "subscribe"), YouTubeClient(db, user) as yt:
|
||||
with quota.attribute(user.id, quota.QuotaAction.CHANNELS_SUBSCRIBE), YouTubeClient(db, user) as yt:
|
||||
yt_sub_id = yt.insert_subscription(channel_id)
|
||||
# Enrich a stub channel (title/thumbnail/subscriber count) so it shows up
|
||||
# properly right away; no video pull here.
|
||||
|
|
@ -356,7 +356,7 @@ def unsubscribe(
|
|||
detail="No YouTube subscription id on record — sync subscriptions first.",
|
||||
)
|
||||
try:
|
||||
with quota.attribute(user.id, "unsubscribe"), YouTubeClient(db, user) as yt:
|
||||
with quota.attribute(user.id, quota.QuotaAction.CHANNELS_UNSUBSCRIBE), YouTubeClient(db, user) as yt:
|
||||
yt.delete_subscription(sub.yt_subscription_id)
|
||||
except YouTubeError as exc:
|
||||
# 422 (a real, explainable error → speaking modal), not 502 which the client treats as
|
||||
|
|
|
|||
|
|
@ -549,7 +549,7 @@ def get_video_detail(
|
|||
}
|
||||
|
||||
try:
|
||||
with quota.attribute(user.id, "video_lookup"), YouTubeClient(db, user) as yt:
|
||||
with quota.attribute(user.id, quota.QuotaAction.VIDEOS_LOOKUP), YouTubeClient(db, user) as yt:
|
||||
items = yt.get_videos([video_id])
|
||||
except YouTubeError as exc:
|
||||
raise HTTPException(status_code=422, detail=f"YouTube lookup failed: {exc}")
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ def sync_youtube(
|
|||
status_code=403,
|
||||
detail="Connect YouTube (read access) to sync your playlists.",
|
||||
)
|
||||
with quota.attribute(user.id, "playlist_sync"):
|
||||
with quota.attribute(user.id, quota.QuotaAction.PLAYLISTS_PULL):
|
||||
return sync_user_playlists(db, user)
|
||||
|
||||
|
||||
|
|
@ -266,7 +266,7 @@ def revert_youtube(
|
|||
status_code=403, detail="Connect YouTube (read access) to sync your playlists."
|
||||
)
|
||||
try:
|
||||
with quota.attribute(user.id, "playlist_sync"):
|
||||
with quota.attribute(user.id, quota.QuotaAction.PLAYLISTS_PULL):
|
||||
return repull_playlist(db, user, pl)
|
||||
except YouTubeError:
|
||||
db.rollback()
|
||||
|
|
@ -298,7 +298,7 @@ def push_plan(
|
|||
status_code=403, detail="Enable YouTube editing in Settings first."
|
||||
)
|
||||
try:
|
||||
with quota.attribute(user.id, "playlist_push"):
|
||||
with quota.attribute(user.id, quota.QuotaAction.PLAYLISTS_PUSH):
|
||||
plan = plan_push(db, user, pl)
|
||||
except YouTubeError:
|
||||
raise HTTPException(status_code=422, detail="Couldn't read the playlist on YouTube.")
|
||||
|
|
@ -322,7 +322,7 @@ def push(
|
|||
status_code=403, detail="Enable YouTube editing in Settings first."
|
||||
)
|
||||
try:
|
||||
with quota.attribute(user.id, "playlist_push"):
|
||||
with quota.attribute(user.id, quota.QuotaAction.PLAYLISTS_PUSH):
|
||||
plan = plan_push(db, user, pl)
|
||||
if plan["units_estimate"] > quota.remaining_today(db):
|
||||
raise HTTPException(
|
||||
|
|
@ -418,7 +418,7 @@ def delete_playlist(
|
|||
status_code=403, detail="Enable YouTube editing in Settings first."
|
||||
)
|
||||
try:
|
||||
with quota.attribute(user.id, "playlist_delete"):
|
||||
with quota.attribute(user.id, quota.QuotaAction.PLAYLISTS_DELETE):
|
||||
with YouTubeClient(db, user) as yt:
|
||||
yt.delete_playlist(pl.yt_playlist_id)
|
||||
except YouTubeError:
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ def sync_subscriptions(
|
|||
detail="Connect your YouTube account (read access) to import subscriptions.",
|
||||
)
|
||||
before = quota.units_used_today(db)
|
||||
with quota.attribute(user.id, "sync_subscriptions"):
|
||||
with quota.attribute(user.id, quota.QuotaAction.SUBSCRIPTIONS_PULL):
|
||||
result = import_subscriptions(db, user)
|
||||
result["quota_used_estimate"] = quota.units_used_today(db) - before
|
||||
result["quota_remaining_today"] = quota.remaining_today(db)
|
||||
|
|
@ -63,7 +63,7 @@ def sync_backfill(
|
|||
max_channels: int = 25,
|
||||
) -> dict:
|
||||
before = quota.units_used_today(db)
|
||||
with quota.attribute(user.id, "backfill_recent"):
|
||||
with quota.attribute(user.id, quota.QuotaAction.VIDEOS_BACKFILL_RECENT):
|
||||
result = run_recent_backfill(db, _user_channels(db, user), max_channels=max_channels)
|
||||
result["quota_used_estimate"] = quota.units_used_today(db) - before
|
||||
return result
|
||||
|
|
@ -74,7 +74,7 @@ def sync_enrich(
|
|||
user: User = Depends(require_human), db: Session = Depends(get_db)
|
||||
) -> dict:
|
||||
before = quota.units_used_today(db)
|
||||
with quota.attribute(user.id, "enrich"):
|
||||
with quota.attribute(user.id, quota.QuotaAction.VIDEOS_ENRICH):
|
||||
enriched = run_enrich(db)
|
||||
return {
|
||||
"enriched": enriched,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue