handle error state bulk update, add bulk clear error

This commit is contained in:
Simon
2025-07-22 19:02:31 +07:00
parent 5cee7af233
commit 7e8ced001d
5 changed files with 41 additions and 7 deletions

View File

@@ -89,12 +89,15 @@ class BulkUpdateDowloadQuerySerializer(serializers.Serializer):
vid_type = serializers.ChoiceField( vid_type = serializers.ChoiceField(
choices=VideoTypeEnum.values_known(), required=False choices=VideoTypeEnum.values_known(), required=False
) )
error = serializers.BooleanField(required=False, allow_null=True)
class BulkUpdateDowloadDataSerializer(serializers.Serializer): class BulkUpdateDowloadDataSerializer(serializers.Serializer):
"""serialize data""" """serialize data"""
status = serializers.ChoiceField(choices=["pending", "ignore", "priority"]) status = serializers.ChoiceField(
choices=["pending", "ignore", "priority", "clear_error"]
)
class DownloadQueueItemUpdateSerializer(serializers.Serializer): class DownloadQueueItemUpdateSerializer(serializers.Serializer):

View File

@@ -30,27 +30,42 @@ class PendingInteract:
_, _ = ElasticWrap(path).post(data=data) _, _ = ElasticWrap(path).post(data=data)
def update_bulk( def update_bulk(
self, channel_id: str | None, vid_type: str | None, new_status: str self,
channel_id: str | None,
vid_type: str | None,
new_status: str,
error: bool | None = None,
): ):
"""update status in bulk""" """update status in bulk"""
must_list = [{"term": {"status": {"value": self.status}}}] must_list = [{"term": {"status": {"value": self.status}}}]
must_not_list = []
if channel_id: if channel_id:
must_list.append({"term": {"channel_id": {"value": channel_id}}}) must_list.append({"term": {"channel_id": {"value": channel_id}}})
if vid_type: if vid_type:
must_list.append({"term": {"vid_type": {"value": vid_type}}}) must_list.append({"term": {"vid_type": {"value": vid_type}}})
if error is not None:
exists = {"exists": {"field": "message"}}
if error:
must_list.append(exists) # type: ignore
else:
must_not_list.append(exists)
if new_status == "priority": if new_status == "priority":
source = """ source = """
ctx._source.status = 'pending'; ctx._source.status = 'pending';
ctx._source.auto_start = true; ctx._source.auto_start = true;
ctx._source.message = null; ctx._source.message = null;
""" """
elif new_status == "clear_error":
source = "ctx._source.message = null"
else: else:
source = f"ctx._source.status = '{new_status}'" source = f"ctx._source.status = '{new_status}'"
data = { data = {
"query": {"bool": {"must": must_list}}, "query": {"bool": {"must": must_list, "must_not": must_not_list}},
"script": {"source": source, "lang": "painless"}, "script": {"source": source, "lang": "painless"},
} }

View File

@@ -155,9 +155,13 @@ class DownloadApiListView(ApiBaseView):
status_filter = validated_query.get("filter") status_filter = validated_query.get("filter")
channel = validated_query.get("channel") channel = validated_query.get("channel")
vid_type = validated_query.get("vid_type") vid_type = validated_query.get("vid_type")
error = validated_query.get("error")
PendingInteract(status=status_filter).update_bulk( PendingInteract(status=status_filter).update_bulk(
channel_id=channel, vid_type=vid_type, new_status=new_status channel_id=channel,
vid_type=vid_type,
new_status=new_status,
error=error,
) )
if new_status == "priority": if new_status == "priority":

View File

@@ -1,18 +1,20 @@
import APIClient from '../../functions/APIClient'; import APIClient from '../../functions/APIClient';
type FilterType = 'ignore' | 'pending'; type FilterType = 'ignore' | 'pending';
export type DownloadQueueStatus = 'ignore' | 'pending' | 'priority'; export type DownloadQueueStatus = 'ignore' | 'pending' | 'priority' | 'clear_error';
const updateDownloadQueueByFilter = async ( const updateDownloadQueueByFilter = async (
filter: FilterType, filter: FilterType,
channel: string | null, channel: string | null,
vid_type: string | null, vid_type: string | null,
error: string | null,
status: DownloadQueueStatus, status: DownloadQueueStatus,
) => { ) => {
const searchParams = new URLSearchParams(); const searchParams = new URLSearchParams();
if (filter) searchParams.append('filter', filter); if (filter) searchParams.append('filter', filter);
if (channel) searchParams.append('channel', channel); if (channel) searchParams.append('channel', channel);
if (vid_type) searchParams.append('vid_type', vid_type); if (vid_type) searchParams.append('vid_type', vid_type);
if (error) searchParams.append('error', error);
return APIClient(`/api/download/?${searchParams.toString()}`, { return APIClient(`/api/download/?${searchParams.toString()}`, {
method: 'PATCH', method: 'PATCH',

View File

@@ -162,6 +162,7 @@ const Download = () => {
showIgnoredFilter, showIgnoredFilter,
channelFilterFromUrl, channelFilterFromUrl,
vidTypeFilterFromUrl, vidTypeFilterFromUrl,
errorFilterFromUrl,
status, status,
); );
setRefresh(true); setRefresh(true);
@@ -467,16 +468,22 @@ const Download = () => {
<h3>Bulk actions</h3> <h3>Bulk actions</h3>
<p> <p>
Applied filtered by status <i>'{showIgnoredFilter}'</i> Applied filtered by status <i>'{showIgnoredFilter}'</i>
{vidTypeFilterFromUrl && (
<span>
{' '}
and by type: <i>'{vidTypeFilterFromUrl}'</i>
</span>
)}
{channelFilterFromUrl && ( {channelFilterFromUrl && (
<span> <span>
{' '} {' '}
and by channel: <i>'{channel_filter_name}'</i> and by channel: <i>'{channel_filter_name}'</i>
</span> </span>
)} )}
{vidTypeFilterFromUrl && ( {errorFilterFromUrl && (
<span> <span>
{' '} {' '}
and by type: <i>'{vidTypeFilterFromUrl}'</i> and by error state: <i>'{errorFilterFromUrl}'</i>
</span> </span>
)} )}
</p> </p>
@@ -489,6 +496,9 @@ const Download = () => {
<div className="button-box"> <div className="button-box">
<Button onClick={() => handleBulkStatusUpdate('ignore')}>Ignore</Button> <Button onClick={() => handleBulkStatusUpdate('ignore')}>Ignore</Button>
<Button onClick={() => handleBulkStatusUpdate('priority')}>Download Now</Button> <Button onClick={() => handleBulkStatusUpdate('priority')}>Download Now</Button>
<Button onClick={() => handleBulkStatusUpdate('clear_error')}>
Clear Errors
</Button>
</div> </div>
)} )}
</div> </div>