automatyzacje-comit3
This commit is contained in:
@@ -172,7 +172,9 @@ def _without_smart_queue_label(value: str | None) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def _has_stalled_label(value: str | None) -> bool:
|
def _has_stalled_label(value: str | None) -> bool:
|
||||||
return SMART_QUEUE_STALLED_LABEL in _label_names(value)
|
# Note: Stalled is treated case-insensitively so manually edited labels still block Smart Queue.
|
||||||
|
target = SMART_QUEUE_STALLED_LABEL.casefold()
|
||||||
|
return any(label.casefold() == target for label in _label_names(value))
|
||||||
|
|
||||||
|
|
||||||
def _without_queue_technical_labels(value: str | None) -> str:
|
def _without_queue_technical_labels(value: str | None) -> str:
|
||||||
@@ -182,7 +184,7 @@ def _without_queue_technical_labels(value: str | None) -> str:
|
|||||||
def _ensure_stalled_label(client: Any, torrent_hash: str, current_label: str = '') -> bool:
|
def _ensure_stalled_label(client: Any, torrent_hash: str, current_label: str = '') -> bool:
|
||||||
labels = [label for label in _label_names(current_label) if label != SMART_QUEUE_LABEL]
|
labels = [label for label in _label_names(current_label) if label != SMART_QUEUE_LABEL]
|
||||||
changed = False
|
changed = False
|
||||||
if SMART_QUEUE_STALLED_LABEL not in labels:
|
if not any(label.casefold() == SMART_QUEUE_STALLED_LABEL.casefold() for label in labels):
|
||||||
labels.append(SMART_QUEUE_STALLED_LABEL)
|
labels.append(SMART_QUEUE_STALLED_LABEL)
|
||||||
changed = True
|
changed = True
|
||||||
if SMART_QUEUE_LABEL in _label_names(current_label):
|
if SMART_QUEUE_LABEL in _label_names(current_label):
|
||||||
@@ -476,7 +478,9 @@ def check(profile: dict | None = None, user_id: int | None = None, force: bool =
|
|||||||
return {'ok': True, 'enabled': False, 'paused': [], 'resumed': [], 'labels_restored': restored, 'message': 'Smart Queue disabled'}
|
return {'ok': True, 'enabled': False, 'paused': [], 'resumed': [], 'labels_restored': restored, 'message': 'Smart Queue disabled'}
|
||||||
|
|
||||||
torrents = rtorrent.list_torrents(profile)
|
torrents = rtorrent.list_torrents(profile)
|
||||||
excluded = _excluded_hashes(profile_id, user_id)
|
# Note: Torrents marked as Stalled are treated as queue-blocked even when there are no other pending downloads.
|
||||||
|
stalled_label_hashes = {str(t.get('hash') or '') for t in torrents if _has_stalled_label(str(t.get('label') or '')) and t.get('hash')}
|
||||||
|
excluded = _excluded_hashes(profile_id, user_id) | stalled_label_hashes
|
||||||
manage_stopped = bool(settings.get('manage_stopped'))
|
manage_stopped = bool(settings.get('manage_stopped'))
|
||||||
def is_managed_hold(t: dict[str, Any]) -> bool:
|
def is_managed_hold(t: dict[str, Any]) -> bool:
|
||||||
return _has_smart_queue_label(str(t.get('label') or ''))
|
return _has_smart_queue_label(str(t.get('label') or ''))
|
||||||
@@ -622,6 +626,6 @@ def check(profile: dict | None = None, user_id: int | None = None, force: bool =
|
|||||||
| {str(t.get('hash') or '') for t in stopped if _has_smart_queue_label(str(t.get('label') or '')) and str(t.get('hash') or '') not in set(resumed)}
|
| {str(t.get('hash') or '') for t in stopped if _has_smart_queue_label(str(t.get('label') or '')) and str(t.get('hash') or '') not in set(resumed)}
|
||||||
)
|
)
|
||||||
restored = _cleanup_auto_labels(c, profile_id, torrents, keep_labels, manage_stopped)
|
restored = _cleanup_auto_labels(c, profile_id, torrents, keep_labels, manage_stopped)
|
||||||
details = {'excluded': len(excluded), 'enabled': bool(settings.get('enabled')), 'auto_label': SMART_QUEUE_LABEL, 'stalled_label': SMART_QUEUE_STALLED_LABEL, 'stalled_labeled': stalled_labeled, 'labels_restored': restored, 'labels_failed': label_failed, 'start_failed': start_failed, 'start_no_effect': start_no_effect, 'start_results': start_results, 'resume_requested': resume_requested, 'active_verified': active_verified, 'waiting_labeled': len(to_label_waiting), 'manage_stopped': manage_stopped, 'max_active_downloads': max_active, 'active_before': len(downloading), 'active_after_expected': active_after_pause + len(resumed), 'paused_planned': len(to_pause), 'resumed_planned': len(to_resume), 'rtorrent_cap': rtorrent_cap}
|
details = {'excluded': len(excluded), 'excluded_stalled': len(stalled_label_hashes), 'enabled': bool(settings.get('enabled')), 'auto_label': SMART_QUEUE_LABEL, 'stalled_label': SMART_QUEUE_STALLED_LABEL, 'stalled_labeled': stalled_labeled, 'labels_restored': restored, 'labels_failed': label_failed, 'start_failed': start_failed, 'start_no_effect': start_no_effect, 'start_results': start_results, 'resume_requested': resume_requested, 'active_verified': active_verified, 'waiting_labeled': len(to_label_waiting), 'manage_stopped': manage_stopped, 'max_active_downloads': max_active, 'active_before': len(downloading), 'active_after_expected': active_after_pause + len(resumed), 'paused_planned': len(to_pause), 'resumed_planned': len(to_resume), 'rtorrent_cap': rtorrent_cap}
|
||||||
add_history(profile_id, 'force_check' if force else 'auto_check', paused, resumed, len(torrents), details, user_id)
|
add_history(profile_id, 'force_check' if force else 'auto_check', paused, resumed, len(torrents), details, user_id)
|
||||||
return {'ok': True, 'enabled': bool(settings.get('enabled')), 'paused': paused, 'resumed': resumed, 'resume_requested': resume_requested, 'waiting_labeled': len(to_label_waiting), 'stalled_labeled': stalled_labeled, 'labels_restored': restored, 'labels_failed': label_failed, 'start_failed': start_failed, 'start_no_effect': start_no_effect, 'active_verified': active_verified, 'rtorrent_cap': rtorrent_cap, 'checked': len(torrents), 'excluded': len(excluded), 'settings': settings}
|
return {'ok': True, 'enabled': bool(settings.get('enabled')), 'paused': paused, 'resumed': resumed, 'resume_requested': resume_requested, 'waiting_labeled': len(to_label_waiting), 'stalled_labeled': stalled_labeled, 'excluded_stalled': len(stalled_label_hashes), 'labels_restored': restored, 'labels_failed': label_failed, 'start_failed': start_failed, 'start_no_effect': start_no_effect, 'active_verified': active_verified, 'rtorrent_cap': rtorrent_cap, 'checked': len(torrents), 'excluded': len(excluded), 'settings': settings}
|
||||||
|
|||||||
@@ -1317,49 +1317,67 @@ body.mobile-mode .mobile-card {
|
|||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
background: var(--bs-secondary-bg);
|
background: var(--bs-secondary-bg);
|
||||||
font-size: 0.78rem;
|
font-size: 0.78rem;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
.automation-history-toolbar {
|
.automation-history-toolbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
/* Note: Automation history has fixed compact metadata columns and a flexible Actions column, so long JSON cannot overlap Time/Rule. */
|
||||||
.automation-history-table {
|
.automation-history-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
table-layout: fixed;
|
table-layout: fixed;
|
||||||
|
white-space: normal;
|
||||||
}
|
}
|
||||||
.automation-history-table th,
|
.automation-history-table th,
|
||||||
.automation-history-table td {
|
.automation-history-table td {
|
||||||
|
min-width: 0;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
.automation-history-table th:nth-child(1),
|
.automation-history-table th:nth-child(1),
|
||||||
.automation-history-table td:nth-child(1) {
|
.automation-history-table td:nth-child(1) {
|
||||||
width: 10.5rem;
|
width: 9rem;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.automation-history-table th:nth-child(2),
|
.automation-history-table th:nth-child(2),
|
||||||
.automation-history-table td:nth-child(2) {
|
.automation-history-table td:nth-child(2) {
|
||||||
width: 13rem;
|
width: 11rem;
|
||||||
|
overflow: hidden;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
.automation-history-table th:nth-child(3),
|
.automation-history-table th:nth-child(3),
|
||||||
.automation-history-table td:nth-child(3) {
|
.automation-history-table td:nth-child(3) {
|
||||||
width: 14rem;
|
width: 12rem;
|
||||||
|
overflow: hidden;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
.automation-history-table th:nth-child(4),
|
.automation-history-table th:nth-child(4),
|
||||||
.automation-history-table td:nth-child(4) {
|
.automation-history-table td:nth-child(4) {
|
||||||
width: auto;
|
width: auto;
|
||||||
min-width: 0;
|
overflow: hidden;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
.automation-history-details {
|
.automation-history-details {
|
||||||
|
display: block;
|
||||||
|
min-width: 0;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
.automation-history-details summary {
|
.automation-history-details summary {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
list-style-position: inside;
|
list-style-position: inside;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
white-space: normal;
|
||||||
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
.automation-history-details pre,
|
.automation-history-details pre,
|
||||||
.automation-history-raw {
|
.automation-history-raw {
|
||||||
@@ -1371,6 +1389,7 @@ body.mobile-mode .mobile-card {
|
|||||||
border: 1px solid var(--bs-border-color);
|
border: 1px solid var(--bs-border-color);
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
background: var(--bs-tertiary-bg);
|
background: var(--bs-tertiary-bg);
|
||||||
|
overflow-wrap: anywhere;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user