mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-08-03 07:12:30 +00:00
Add better display in the m3u table for the user to see what we are doing.
This commit is contained in:
parent
4619d09efe
commit
d26dd5f6b3
2 changed files with 175 additions and 16 deletions
|
|
@ -530,6 +530,7 @@ def refresh_single_m3u_account(account_id):
|
|||
|
||||
total_batches = len(batches)
|
||||
completed_batches = 0
|
||||
streams_processed = 0 # Track total streams processed
|
||||
logger.debug(f"Dispatched {len(batches)} parallel tasks for account_id={account_id}.")
|
||||
|
||||
# result = task_group.apply_async()
|
||||
|
|
@ -542,18 +543,47 @@ def refresh_single_m3u_account(account_id):
|
|||
if async_result.ready() and async_result.id not in completed_task_ids: # If the task has completed and we haven't counted it
|
||||
task_result = async_result.result # The result of the task
|
||||
logger.debug(f"Task completed with result: {task_result}")
|
||||
|
||||
# Extract stream counts from result string if available
|
||||
if isinstance(task_result, str):
|
||||
try:
|
||||
created_match = re.search(r"(\d+) created", task_result)
|
||||
updated_match = re.search(r"(\d+) updated", task_result)
|
||||
|
||||
if created_match and updated_match:
|
||||
created_count = int(created_match.group(1))
|
||||
updated_count = int(updated_match.group(1))
|
||||
streams_processed += created_count + updated_count
|
||||
except (AttributeError, ValueError):
|
||||
pass
|
||||
|
||||
completed_batches += 1
|
||||
completed_task_ids.add(async_result.id) # Mark this task as processed
|
||||
|
||||
# Calculate progress
|
||||
progress = int((completed_batches / total_batches) * 100)
|
||||
|
||||
# Calculate elapsed time and estimated remaining time
|
||||
current_elapsed = time.time() - start_time
|
||||
if progress > 0:
|
||||
estimated_total = (current_elapsed / progress) * 100
|
||||
time_remaining = max(0, estimated_total - current_elapsed)
|
||||
else:
|
||||
time_remaining = 0
|
||||
|
||||
# Send progress update via Channels
|
||||
# Don't send 100% because we want to clean up after
|
||||
if progress == 100:
|
||||
progress = 99
|
||||
|
||||
send_m3u_update(account_id, "parsing", progress)
|
||||
send_m3u_update(
|
||||
account_id,
|
||||
"parsing",
|
||||
progress,
|
||||
elapsed_time=current_elapsed,
|
||||
time_remaining=time_remaining,
|
||||
streams_processed=streams_processed
|
||||
)
|
||||
|
||||
# Optionally remove completed task from the group to prevent processing it again
|
||||
result.remove(async_result)
|
||||
|
|
@ -567,7 +597,16 @@ def refresh_single_m3u_account(account_id):
|
|||
|
||||
# Now run cleanup
|
||||
cleanup_streams(account_id)
|
||||
send_m3u_update(account_id, "parsing", 100)
|
||||
# Send final update with complete metrics
|
||||
elapsed_time = time.time() - start_time
|
||||
send_m3u_update(
|
||||
account_id,
|
||||
"parsing",
|
||||
100,
|
||||
elapsed_time=elapsed_time,
|
||||
time_remaining=0,
|
||||
streams_processed=streams_processed
|
||||
)
|
||||
|
||||
end_time = time.time()
|
||||
|
||||
|
|
|
|||
|
|
@ -43,17 +43,18 @@ const M3UTable = () => {
|
|||
return buildDownloadingStats(data);
|
||||
|
||||
case 'processing_groups':
|
||||
return 'Processing groups...';
|
||||
return buildGroupProcessingStats(data);
|
||||
|
||||
case 'parsing':
|
||||
return buildParsingStats(data);
|
||||
|
||||
default:
|
||||
return buildParsingStats(data);
|
||||
return data.status === 'error' ? buildErrorStats(data) : `${data.action || 'Processing'}...`;
|
||||
}
|
||||
};
|
||||
|
||||
const buildDownloadingStats = (data) => {
|
||||
if (data.progress == 100) {
|
||||
// fetchChannelGroups();
|
||||
// fetchPlaylists();
|
||||
return 'Download complete!';
|
||||
}
|
||||
|
||||
|
|
@ -61,21 +62,89 @@ const M3UTable = () => {
|
|||
return 'Downloading...';
|
||||
}
|
||||
|
||||
// Format time remaining in minutes:seconds
|
||||
const timeRemaining = data.time_remaining ?
|
||||
`${Math.floor(data.time_remaining / 60)}:${String(Math.floor(data.time_remaining % 60)).padStart(2, '0')}` :
|
||||
'calculating...';
|
||||
|
||||
// Format speed with appropriate unit (KB/s or MB/s)
|
||||
const speed = data.speed >= 1024 ?
|
||||
`${(data.speed / 1024).toFixed(2)} MB/s` :
|
||||
`${Math.round(data.speed)} KB/s`;
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Text size="xs">Downloading: {parseInt(data.progress)}%</Text>
|
||||
{/* <Text size="xs">Speed: {parseInt(data.speed)} KB/s</Text>
|
||||
<Text size="xs">Time Remaining: {parseInt(data.time_remaining)}</Text> */}
|
||||
<Flex direction="column" gap="xs">
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text size="xs" fw={500}>Downloading:</Text>
|
||||
<Text size="xs">{parseInt(data.progress)}%</Text>
|
||||
</Flex>
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text size="xs" fw={500}>Speed:</Text>
|
||||
<Text size="xs">{speed}</Text>
|
||||
</Flex>
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text size="xs" fw={500}>Time left:</Text>
|
||||
<Text size="xs">{timeRemaining}</Text>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const buildGroupProcessingStats = (data) => {
|
||||
if (data.progress == 100) {
|
||||
return 'Groups processed!';
|
||||
}
|
||||
|
||||
if (data.progress == 0) {
|
||||
return 'Processing groups...';
|
||||
}
|
||||
|
||||
// Format time displays if available
|
||||
const elapsedTime = data.elapsed_time ?
|
||||
`${Math.floor(data.elapsed_time / 60)}:${String(Math.floor(data.elapsed_time % 60)).padStart(2, '0')}` :
|
||||
null;
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Flex direction="column" gap="xs">
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text size="xs" fw={500}>Processing groups:</Text>
|
||||
<Text size="xs">{parseInt(data.progress)}%</Text>
|
||||
</Flex>
|
||||
{elapsedTime && (
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text size="xs" fw={500}>Elapsed:</Text>
|
||||
<Text size="xs">{elapsedTime}</Text>
|
||||
</Flex>
|
||||
)}
|
||||
{data.groups_processed && (
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text size="xs" fw={500}>Groups:</Text>
|
||||
<Text size="xs">{data.groups_processed}</Text>
|
||||
</Flex>
|
||||
)}
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const buildErrorStats = (data) => {
|
||||
return (
|
||||
<Box>
|
||||
<Flex direction="column" gap="xs">
|
||||
<Flex align="center">
|
||||
<Text size="xs" fw={500} color="red">Error:</Text>
|
||||
</Flex>
|
||||
<Text size="xs" color="red">{data.error || "Unknown error occurred"}</Text>
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const buildParsingStats = (data) => {
|
||||
if (data.progress == 100) {
|
||||
// fetchStreams();
|
||||
// fetchChannelGroups();
|
||||
// fetchEPGData();
|
||||
// fetchPlaylists();
|
||||
return 'Parsing complete!';
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +152,43 @@ const M3UTable = () => {
|
|||
return 'Parsing...';
|
||||
}
|
||||
|
||||
return `Parsing: ${data.progress}%`;
|
||||
// Format time displays
|
||||
const timeRemaining = data.time_remaining ?
|
||||
`${Math.floor(data.time_remaining / 60)}:${String(Math.floor(data.time_remaining % 60)).padStart(2, '0')}` :
|
||||
'calculating...';
|
||||
|
||||
const elapsedTime = data.elapsed_time ?
|
||||
`${Math.floor(data.elapsed_time / 60)}:${String(Math.floor(data.elapsed_time % 60)).padStart(2, '0')}` :
|
||||
'0:00';
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Flex direction="column" gap="xs">
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text size="xs" fw={500}>Parsing:</Text>
|
||||
<Text size="xs">{parseInt(data.progress)}%</Text>
|
||||
</Flex>
|
||||
{data.elapsed_time && (
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text size="xs" fw={500}>Elapsed:</Text>
|
||||
<Text size="xs">{elapsedTime}</Text>
|
||||
</Flex>
|
||||
)}
|
||||
{data.time_remaining && (
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text size="xs" fw={500}>Remaining:</Text>
|
||||
<Text size="xs">{timeRemaining}</Text>
|
||||
</Flex>
|
||||
)}
|
||||
{data.streams_processed && (
|
||||
<Flex justify="space-between" align="center">
|
||||
<Text size="xs" fw={500}>Streams:</Text>
|
||||
<Text size="xs">{data.streams_processed}</Text>
|
||||
</Flex>
|
||||
)}
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
const toggleActive = async (playlist) => {
|
||||
|
|
@ -143,8 +248,23 @@ const M3UTable = () => {
|
|||
|
||||
return generateStatusString(refreshProgress[row.id]);
|
||||
},
|
||||
size: 150,
|
||||
minSize: 80,
|
||||
size: 180,
|
||||
minSize: 150,
|
||||
Cell: ({ cell }) => {
|
||||
const value = cell.getValue();
|
||||
|
||||
// Return a visual component for the status
|
||||
if (typeof value === 'object') {
|
||||
return value;
|
||||
}
|
||||
|
||||
// For simple string statuses
|
||||
return (
|
||||
<Text size="xs">
|
||||
{value}
|
||||
</Text>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
header: 'Active',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue