- Uploads: one at a time per user and ten an hour, each refused only after its body arrived; the history read an entry at a time (32 MiB cap), a Watch later list capped at YouTube's 5000, a user's kept videos at 200k; any unreadable shape is a 422, not a 500. - Quota: Watch later lookups stop at the backfill reserve and at a per-user daily share; what is not asked about waits, known videos still go in, and the shorts job retries the rest. - Staging and settling share one per-user advisory lock (no deadlock); a run settles only the rows it read, so a row staged meanwhile is never called gone. - A failed run's notice names a translated failure, never the upstream's text. - The status says when an import is queued; the page watches it to its end even when left, then reads the feed, its counts and the playlists again. - Settings: one live region, the zone kept (unavailable) while a run goes, focus handed back, a missed drop kept from the browser, an oversize file refused before it is sent. - Scheduler and run lists show Takeout runs by the importing user.
328 lines
17 KiB
JSON
328 lines
17 KiB
JSON
{
|
|
"title": "Settings",
|
|
"tabs": {
|
|
"appearance": "Appearance",
|
|
"notifications": "Notifications",
|
|
"account": "Account",
|
|
"diagnostics": "Diagnostics",
|
|
"downloads": "Downloads",
|
|
"tokens": "API tokens"
|
|
},
|
|
"plexSync": {
|
|
"title": "Plex watch sync",
|
|
"intro": "Sync your watched / in-progress status between Plex and Siftlode. Turning this on imports your existing Plex history now (Plex wins); ongoing two-way sync follows.",
|
|
"toggle": "Two-way sync with Plex",
|
|
"toggleHint": "Uses this server's Plex account. Turning it on imports your Plex watch history once.",
|
|
"importNow": "Import from Plex now",
|
|
"imported": "Imported from Plex: {{watched}} watched, {{in_progress}} in progress.",
|
|
"lastSync": "Last import: {{when}}",
|
|
"never": "Not imported yet",
|
|
"importing": "Importing your Plex watch history…"
|
|
},
|
|
"takeout": {
|
|
"title": "YouTube history",
|
|
"intro": "Upload “watch-history.json” from your Google Takeout export (and “Watch later-videos.csv”, if you have it). Videos known here show as watched; the rest are remembered and marked watched once they arrive here. Shorts are skipped, and nothing you set here is overwritten.",
|
|
"drop": "Drop the files here, or choose them",
|
|
"dropActive": "Drop to upload",
|
|
"uploading": "Uploading {{name}}…",
|
|
"read_one": "{{name}}: {{n}} video read",
|
|
"read_other": "{{name}}: {{n}} videos read",
|
|
"running": "Processing…",
|
|
"last": "Last import: {{when}}",
|
|
"failed": "The last import ({{when}}) failed. Upload the file again to retry.",
|
|
"interrupted": "The last import ({{when}}) was cut off by a server restart. Upload the file again to finish it.",
|
|
"newImport": "New import",
|
|
"loadFailed": "Couldn't load the last import",
|
|
"howTo": "How to export from Takeout?",
|
|
"howToBody": "At takeout.google.com select only “YouTube and YouTube Music”. In its options keep only “history” and “playlists”, and choose JSON for the history. Untick “videos”, or every video you ever uploaded comes with it.",
|
|
"count": {
|
|
"watched_one": "{{n}} watched",
|
|
"watched_other": "{{n}} watched",
|
|
"waiting_one": "{{n}} remembered",
|
|
"waiting_other": "{{n}} remembered",
|
|
"short_one": "{{n}} Short skipped",
|
|
"short_other": "{{n}} Shorts skipped",
|
|
"kept_one": "{{n}} left as you set it here",
|
|
"kept_other": "{{n}} left as you set them here",
|
|
"added_one": "{{n}} added to Watch later",
|
|
"added_other": "{{n}} added to Watch later",
|
|
"present_one": "{{n}} already in Watch later",
|
|
"present_other": "{{n}} already in Watch later",
|
|
"missing_one": "{{n}} no longer on YouTube",
|
|
"missing_other": "{{n}} no longer on YouTube",
|
|
"laterWaiting_one": "{{n}} waiting for Watch later",
|
|
"laterWaiting_other": "{{n}} waiting for Watch later"
|
|
},
|
|
"tooLarge": "{{name}} is larger than {{limit}} — the import takes files up to that size"
|
|
},
|
|
"save": {
|
|
"saving": "Saving…",
|
|
"saved": "Settings saved",
|
|
"failed": "Couldn't save"
|
|
},
|
|
"appearance": {
|
|
"colorScheme": "Color scheme",
|
|
"display": "Display",
|
|
"darkMode": "Dark mode",
|
|
"backgroundImage": "Background image",
|
|
"backgroundImageHint": "Show a subtle per-scheme backdrop image behind the app so the glass surfaces have something to refract. Off = flat colour.",
|
|
"backgroundFade": "Image fade",
|
|
"performanceMode": "Performance mode",
|
|
"performanceModeHint": "Turns off the translucent glass blur and soft shadows for snappier rendering on slower machines. On this device only.",
|
|
"showHints": "Show hints",
|
|
"showHintsHint": "These little hover explanations. Turn them off once you know your way around.",
|
|
"railLabels": "Labels in the side menu",
|
|
"railLabelsHint": "A short name under each icon in the left menu. The menu stays as narrow; it only grows taller.",
|
|
"startup": "Startup",
|
|
"startOnHome": "Start on Home",
|
|
"startOnHomeHint": "Every launch opens “What should I watch?”. Off = pick up on the module you left open.",
|
|
"textSize": "Text size"
|
|
},
|
|
"notifications": {
|
|
"title": "Notifications",
|
|
"sound": "Sound on notifications",
|
|
"soundHint": "Play a short tone when a notification needs your attention (e.g. errors, prompts).",
|
|
"autoDismiss": "Auto-dismiss toasts",
|
|
"autoDismissHint": "When off, pop-up toasts stay until you close them. When on, they fade after the set time; one with a button (Undo) stays at least 8 seconds.",
|
|
"dismissAfter": "Dismiss after",
|
|
"sendTest": "Send a test notification",
|
|
"testTitle": "Test notification",
|
|
"testMessage": "This is what a notification looks like."
|
|
},
|
|
"account": {
|
|
"title": "Account",
|
|
"lastLogin": "Last sign-in: {{time}}",
|
|
"lastLoginNone": "No sign-in recorded yet",
|
|
"youtubeAccess": "YouTube access",
|
|
"youtubeAccessIntro": "Sign-in only shares your name and email. YouTube access is granted separately, below — each is optional and revocable anytime in your Google Account.",
|
|
"readTitle": "Read subscriptions (your Feed)",
|
|
"readGrantedHint": "Granted. Siftlode reads the channels you follow to build your Feed. It never changes your YouTube account with this.",
|
|
"readEnableHint": "Read-only access to your subscriptions — required to build your Feed. Siftlode can't modify anything with it.",
|
|
"writeTitle": "Unsubscribe (write)",
|
|
"writeGrantedHint": "Granted. You can unsubscribe from channels on YouTube from inside Siftlode. It only writes when you ask it to.",
|
|
"writeEnableHint": "Lets Siftlode unsubscribe from channels on YouTube for you. Optional — skip it to stay read-only.",
|
|
"granted": "Granted",
|
|
"enable": "Enable",
|
|
"enableHint": "Redirects to Google to grant the permission. Google shows an “unverified app” notice — that's expected; click Advanced → Go to Siftlode.",
|
|
"walkMeThrough": "Walk me through setup",
|
|
"dangerZone": "Danger zone",
|
|
"deleteHint": "Permanently delete your account and all your data — subscriptions, tags, watch history, playlists and settings. This can't be undone.",
|
|
"deleteAccount": "Delete my account",
|
|
"deleteTitle": "Delete your account?",
|
|
"deleteConfirm": "This permanently erases your account and all your data (subscriptions, tags, watch/saved/hidden state, playlists, settings). It can't be undone.",
|
|
"deleteConfirmButton": "Delete everything",
|
|
"signInMethods": "Sign-in methods",
|
|
"googleLink": {
|
|
"title": "Google account",
|
|
"connected": "Connected",
|
|
"connectedHint": "Your Google account is linked. You can sign in with Google and grant YouTube access below.",
|
|
"connectHint": "Link a Google account to sign in with Google and to enable YouTube access for your Feed.",
|
|
"connect": "Connect Google",
|
|
"linked": "Google account linked",
|
|
"conflict": "That Google account is already linked to a different Siftlode account",
|
|
"mismatch": "That's a different Google account than the one already linked here. Sign in with the linked one.",
|
|
"error": "Couldn't link the Google account. Please try again.",
|
|
"signedInAs": "Signed in with Google as"
|
|
},
|
|
"googleCancelled": "Google sign-in was cancelled",
|
|
"password": {
|
|
"title": "Password",
|
|
"setHint": "A password is set. You can sign in with your email and password.",
|
|
"unsetHint": "No password yet — set one to sign in with your email instead of (or as well as) Google.",
|
|
"set": "Set password",
|
|
"change": "Change password",
|
|
"current": "Current password",
|
|
"new": "New password (min. 10 characters)",
|
|
"save": "Save password",
|
|
"saving": "Saving…",
|
|
"saved": "Password updated for {{email}} — other sessions were signed out and your API tokens revoked",
|
|
"failed": "Couldn't update the password"
|
|
},
|
|
"sessions": {
|
|
"title": "Active sessions",
|
|
"hint": "Sign this account out everywhere else, and revoke its API tokens — handy if you left it signed in on a shared or lost device. You stay signed in here.",
|
|
"action": "Log out other sessions",
|
|
"confirmTitle": "Log out other sessions?",
|
|
"confirmBody": "This signs you out of every other browser and device, and revokes every API token of yours (make new ones for your machines). You'll stay signed in here.",
|
|
"done": "Signed out of all other sessions; API tokens revoked",
|
|
"failed": "Couldn't sign out other sessions. Please try again."
|
|
}
|
|
},
|
|
"downloadAuth": {
|
|
"title": "Download authentication",
|
|
"intro": "Some sites (e.g. a private Facebook group you belong to) only let logged-in members view a video. Paste your browser cookies for a site here and your downloads from it will use your login. Cookies are encrypted, kept private to your account, and only ever sent to the matching site.",
|
|
"configured": "Set · updated {{when}}",
|
|
"notSet": "Not set",
|
|
"set": "Set cookies…",
|
|
"update": "Update…",
|
|
"remove": "Delete",
|
|
"save": "Save",
|
|
"cancel": "Cancel",
|
|
"saving": "Saving…",
|
|
"placeholder": "Paste the contents of your cookies.txt (Netscape format) here",
|
|
"help": "Export a cookies.txt for this site with a browser extension, then paste it here. It's write-only — we never show it back.",
|
|
"saved": "Cookies saved",
|
|
"removed": "Cookies deleted",
|
|
"failed": "Couldn't save those cookies",
|
|
"removeConfirmTitle": "Delete cookies?",
|
|
"removeConfirmBody": "Downloads from this site will stop using your login.",
|
|
"removeConfirmAction": "Delete",
|
|
"loadError": "Couldn't load your download authentication settings"
|
|
},
|
|
"invites": {
|
|
"title": "Access requests",
|
|
"noPending": "No pending requests.",
|
|
"addPlaceholder": "Add an email directly…",
|
|
"add": "Add",
|
|
"decided_one": "{{count}} decided",
|
|
"decided_other": "{{count}} decided",
|
|
"approved": "Approved {{email}} — they can sign in now",
|
|
"approveFailed": "Couldn't approve the request",
|
|
"denyFailed": "Couldn't deny the request",
|
|
"addedToWhitelist": "{{email}} added to the whitelist",
|
|
"inviteHint": "Send them an invitation. Adding an address never mails anyone — this does.",
|
|
"invitedAt": "Invited {{time}}. Sending again will mail them a second time.",
|
|
"inviteLabel": "Send an invitation to {{email}}",
|
|
"invited": "Invitation sent to {{email}}",
|
|
"inviteFailed": "Couldn't send that invitation",
|
|
"inviteTitle": "Send invitation?",
|
|
"inviteConfirm": "Email {{email}} to say their address is whitelisted and Siftlode is open for them.",
|
|
"inviteConfirmAgain": "You already invited {{email}} on {{time}}. Sending now writes to them a second time.",
|
|
"inviteSend": "Send",
|
|
"inviteLang": "Mail language",
|
|
"addFailed": "Couldn't add that email",
|
|
"requested": "requested {{time}}",
|
|
"approveHint": "Approve — whitelist this email and email them they're in.",
|
|
"approve": "Approve",
|
|
"denyHint": "Deny this request.",
|
|
"deny": "Deny",
|
|
"denied": "Request denied",
|
|
"denyTitle": "Deny access request?",
|
|
"denyConfirm": "Deny the access request from {{email}}?",
|
|
"delete": "Delete",
|
|
"deleteLabel": "Delete {{email}} from the whitelist",
|
|
"deleteHint": "Forget this address. A later request from it comes back as a new one.",
|
|
"deleteTitle": "Delete whitelist entry?",
|
|
"deleteConfirm": "Forget {{email}}? Siftlode drops the record, so anyone at that address would have to ask again.",
|
|
"deleteHasAccount": "Someone has registered on this address — manage it under Users & roles, where deleting the account removes this entry too.",
|
|
"deleted": "Whitelist entry deleted",
|
|
"deleteFailed": "Couldn't delete the entry",
|
|
"emailOff": "Email sending is not configured, so nobody gets a verification link and no request reaches you by email. Watch this list and your Notifications instead, and fix it under Configuration → Email / SMTP.",
|
|
"deletedStillAllowed": "Entry deleted, but this address is still allow-listed by the server's configuration, so it keeps access. Remove it from ALLOWED_EMAILS / ADMIN_EMAILS to change that.",
|
|
"deleteConfirmStillAllowed": "Forget {{email}}? Careful: this address is also allow-listed in the server's configuration (ALLOWED_EMAILS / ADMIN_EMAILS), so deleting this row will NOT take its access away — and an ADMIN_EMAILS address is made an admin again on its next Google sign-in.",
|
|
"status": {
|
|
"approved": "Approved",
|
|
"denied": "Denied"
|
|
}
|
|
},
|
|
"diagnostics": {
|
|
"title": "Logging level",
|
|
"level": "Level",
|
|
"levelHint": "At Basic, the log lives only in this browser tab — errors, warnings, page changes and requests — and nothing is sent to the server. Detailed and Full record more and send it to the server for 24 hours, only with your consent.",
|
|
"levels": {
|
|
"INFO": "Basic",
|
|
"DEBUG": "Detailed",
|
|
"TRACE": "Full"
|
|
},
|
|
"consent": {
|
|
"title": {
|
|
"DEBUG": "Turn on detailed logging for 24 hours",
|
|
"TRACE": "Turn on full logging for 24 hours"
|
|
},
|
|
"what": {
|
|
"DEBUG": "We record which buttons, filters and player controls you use, and the values in the address bar.",
|
|
"TRACE": "We record which buttons, filters and player controls you use, the values in the address bar, and the text you type into search."
|
|
},
|
|
"server_one": "The Siftlode server receives this too and keeps it for {{count}} day, so the problem can be tracked down.",
|
|
"server_other": "The Siftlode server receives this too and keeps it for {{count}} days, so the problem can be tracked down.",
|
|
"never": "Passwords, tokens and email addresses are never included.",
|
|
"lapse": "After 24 hours it goes back to “Basic” by itself.",
|
|
"policy": "Privacy policy",
|
|
"cancel": "Cancel",
|
|
"confirm": "Turn on for 24 hours"
|
|
},
|
|
"status": "{{level}} logging · back to “Basic” in {{time}}",
|
|
"revert": "Back to “Basic” now",
|
|
"failed": "Couldn't change the logging level"
|
|
},
|
|
"myLog": {
|
|
"title": "My log",
|
|
"hint": "What this browser tab has recorded. It is gone when the page reloads.",
|
|
"search": "Search the events…",
|
|
"filterLabel": "Filter by level",
|
|
"filters": {
|
|
"all": "All",
|
|
"error": "Errors",
|
|
"warning": "Warnings",
|
|
"info": "Info",
|
|
"detail": "Detailed"
|
|
},
|
|
"count_one": "{{count}} event · newest first",
|
|
"count_other": "{{count}} events · newest first",
|
|
"capped_one": "showing the newest {{shown}} of {{count}}",
|
|
"capped_other": "showing the newest {{shown}} of {{count}}",
|
|
"copy": "Copy",
|
|
"copied_one": "Copied {{count}} event",
|
|
"copied_other": "Copied {{count}} events",
|
|
"copyFailed": "Couldn't copy to the clipboard",
|
|
"clear": "Clear",
|
|
"empty": "No event matches the filter.",
|
|
"emptyAll": "No events yet."
|
|
},
|
|
"downloads": {
|
|
"formats": "Download formats",
|
|
"formatsIntro": "The choices the download dialog offers. The built-in ones are fixed; duplicate one to make your own."
|
|
},
|
|
"tokens": {
|
|
"intro": "A token gives one machine a key to the folders you pick in your Files library — and to nothing else.",
|
|
"new": "New token",
|
|
"empty": "No tokens yet. Make one for your hub or for a script of yours.",
|
|
"rowMenu": "Token actions",
|
|
"expiring": "Expires soon",
|
|
"expired": "Expired",
|
|
"lastUsed": "Last used",
|
|
"neverUsed": "Never used",
|
|
"expiresOn": "Expires {{date}}",
|
|
"expiredOn": "Expired {{date}}",
|
|
"neverExpires": "Never expires",
|
|
"revoke": "Revoke…",
|
|
"revokeTitle": "Revoke “{{name}}”?",
|
|
"revokeBody": "The machine that uses it loses access at its next request. This is final: a new token has to be made in its place.",
|
|
"revokeAction": "Revoke",
|
|
"rights": {
|
|
"list": "List",
|
|
"read": "Read",
|
|
"write": "Write",
|
|
"delete": "Delete"
|
|
},
|
|
"newTitle": "New API token",
|
|
"kind": "Kind of token",
|
|
"hubTitle": "Hub exchange",
|
|
"hubText": "One shared Hub folder; the token may do anything in it.",
|
|
"hubName": "Hub exchange",
|
|
"customTitle": "Custom",
|
|
"customText": "You pick the folders and the rights.",
|
|
"name": "Name",
|
|
"folders": "Folders and rights",
|
|
"noFolders": "You have no folders yet.",
|
|
"expiry": "Expires",
|
|
"expiryOption": {
|
|
"30": "30 days",
|
|
"90": "90 days",
|
|
"365": "1 year",
|
|
"never": "Never"
|
|
},
|
|
"neverWarning": "A token that never expires opens its folders until you revoke it.",
|
|
"create": "Create",
|
|
"madeTitle": "Your token is ready",
|
|
"once": "This is the only time you see it: only its fingerprint is kept. If you lose it, make a new one.",
|
|
"token": "Token",
|
|
"tryIt": "Try it (curl)",
|
|
"copy": "Copy",
|
|
"copied": "Copied",
|
|
"copyField": "Copy: {{field}}",
|
|
"copiedField": "Copied: {{field}}",
|
|
"done": "Done"
|
|
}
|
|
}
|