Bulk clear errors, #build

Changed:
- Added bulk clear error button
- bump yt-dlp
This commit is contained in:
Simon 2025-07-22 23:17:29 +07:00
commit 4f46492298
No known key found for this signature in database
GPG Key ID: 2C15AA5E89985DD4
7 changed files with 43 additions and 9 deletions

View File

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

View File

@ -30,27 +30,42 @@ class PendingInteract:
_, _ = ElasticWrap(path).post(data=data)
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"""
must_list = [{"term": {"status": {"value": self.status}}}]
must_not_list = []
if channel_id:
must_list.append({"term": {"channel_id": {"value": channel_id}}})
if 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":
source = """
ctx._source.status = 'pending';
ctx._source.auto_start = true;
ctx._source.message = null;
"""
elif new_status == "clear_error":
source = "ctx._source.message = null"
else:
source = f"ctx._source.status = '{new_status}'"
data = {
"query": {"bool": {"must": must_list}},
"query": {"bool": {"must": must_list, "must_not": must_not_list}},
"script": {"source": source, "lang": "painless"},
}

View File

@ -155,9 +155,13 @@ class DownloadApiListView(ApiBaseView):
status_filter = validated_query.get("filter")
channel = validated_query.get("channel")
vid_type = validated_query.get("vid_type")
error = validated_query.get("error")
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":

View File

@ -6,5 +6,5 @@ pylint==3.3.7
pytest-django==4.11.1
pytest==8.4.1
python-dotenv==1.1.1
requirementscheck==0.0.6
requirementscheck==0.1.0
types-requests==2.32.4.20250611

View File

@ -12,4 +12,4 @@ requests==2.32.4
ryd-client==0.0.6
uvicorn==0.35.0
whitenoise==6.9.0
yt-dlp[default]==2025.6.30
yt-dlp[default]==2025.7.21

View File

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

View File

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