MCPcopy Create free account
hub / github.com/DialmasterOrg/Youtarr / enqueueAutoRetryJob

Method enqueueAutoRetryJob

server/modules/downloadModule.js:114–162  ·  view source on GitHub ↗

* Enqueue a follow-up URL-list job for videos that failed with a transient * HTTP 403. Owning channels are resolved so channel-tier settings (quality, * audio format, subfolder routing) apply on the retry; the source job's * overrideSettings carry dialog-picked options through for manual an

({ retryVideos, autoRetryAttempt, runId, sourceJobData = {} })

Source from the content-addressed store, hash-verified

112 * @param {Object} params.sourceJobData - the failing job's data payload
113 */
114 async enqueueAutoRetryJob({ retryVideos, autoRetryAttempt, runId, sourceJobData = {} }) {
115 if (!Array.isArray(retryVideos) || retryVideos.length === 0) return;
116
117 const ownerChannelMap = { ...(this.getJobDataValue(sourceJobData, 'ownerChannelMap') || {}) };
118 const unmappedIds = retryVideos
119 .map((video) => video.youtubeId)
120 .filter((id) => id && !ownerChannelMap[id]);
121 if (unmappedIds.length > 0) {
122 try {
123 const rows = await ChannelVideo.findAll({
124 where: { youtube_id: unmappedIds },
125 attributes: ['youtube_id', 'channel_id'],
126 });
127 for (const row of rows) {
128 if (row.channel_id) ownerChannelMap[row.youtube_id] = row.channel_id;
129 }
130 } catch (err) {
131 logger.warn({ err }, 'Could not resolve owning channels for auto-retry; falling back to global settings');
132 }
133 }
134
135 // A single owning channel lets doSpecificDownloads resolve channel-tier
136 // quality/audio/skip-video-folder; with mixed channels those fall back to
137 // the copied override or global settings (subfolder routing still resolves
138 // per video via ownerChannelMap in post-processing).
139 const mappedChannelIds = new Set(
140 retryVideos.map((video) => ownerChannelMap[video.youtubeId]).filter(Boolean)
141 );
142 const channelId = this.getJobDataValue(sourceJobData, 'channelId')
143 || (mappedChannelIds.size === 1 ? [...mappedChannelIds][0] : null);
144 const effectiveQuality = this.getJobDataValue(sourceJobData, 'effectiveQuality') || null;
145
146 const body = {
147 urls: retryVideos.map((video) => video.url),
148 overrideSettings: { ...this.getOverrideSettings(sourceJobData) },
149 jobLabel: autoRetryJobLabel(retryVideos.length),
150 autoRetryAttempt,
151 };
152 if (Object.keys(ownerChannelMap).length > 0) body.ownerChannelMap = ownerChannelMap;
153 if (channelId) body.channelId = channelId;
154 if (effectiveQuality) body.effectiveQuality = effectiveQuality;
155 if (runId) body.runId = runId;
156
157 logger.info(
158 { videoCount: retryVideos.length, autoRetryAttempt, channelId, runId },
159 'Enqueueing auto-retry job for transient 403 failures'
160 );
161 await this.doSpecificDownloads({ body });
162 }
163
164 async doChannelDownloads(jobData = {}, isNextJob = false) {
165 const overrideSettings = this.getOverrideSettings(jobData);

Callers 2

constructorMethod · 0.95

Calls 4

getJobDataValueMethod · 0.95
getOverrideSettingsMethod · 0.95
doSpecificDownloadsMethod · 0.95
autoRetryJobLabelFunction · 0.85

Tested by

no test coverage detected