mirror of
https://github.com/chibicitiberiu/ytsm.git
synced 2024-02-24 05:43:31 +00:00
Added progress notifications.
This commit is contained in:
parent
15f52a1d23
commit
3dd0f564b7
@ -4,6 +4,7 @@ from threading import Lock
|
||||
|
||||
from apscheduler.triggers.cron import CronTrigger
|
||||
|
||||
from YtManagerApp.management.notification_manager import OPERATION_ID_SYNCHRONIZE
|
||||
from YtManagerApp.scheduler import scheduler
|
||||
from YtManagerApp.management.appconfig import appconfig
|
||||
from YtManagerApp.management.downloader import fetch_thumbnail, downloader_process_all, downloader_process_subscription
|
||||
@ -18,7 +19,7 @@ __lock = Lock()
|
||||
_ENABLE_UPDATE_STATS = True
|
||||
|
||||
|
||||
def __check_new_videos_sub(subscription: Subscription, yt_api: youtube.YoutubeAPI):
|
||||
def __check_new_videos_sub(subscription: Subscription, yt_api: youtube.YoutubeAPI, progress_callback):
|
||||
# Get list of videos
|
||||
for item in yt_api.playlist_items(subscription.playlist_id):
|
||||
results = Video.objects.filter(video_id=item.resource_video_id, subscription=subscription)
|
||||
@ -100,6 +101,10 @@ def __fetch_thumbnails():
|
||||
__fetch_thumbnails_obj(Video.objects.filter(icon_best__istartswith='http'), 'video', 'video_id')
|
||||
|
||||
|
||||
def __compute_progress(stage, stage_count, items, total_items):
|
||||
stage_percent = float(stage) / stage_count
|
||||
|
||||
|
||||
def synchronize():
|
||||
if not __lock.acquire(blocking=False):
|
||||
# Synchronize already running in another thread
|
||||
@ -108,7 +113,12 @@ def synchronize():
|
||||
|
||||
try:
|
||||
log.info("Running scheduled synchronization... ")
|
||||
notification_manager.notify_status_update(f'Synchronization started for all subscriptions.')
|
||||
notification_manager.notify_status_operation_progress(
|
||||
OPERATION_ID_SYNCHRONIZE,
|
||||
'Running scheduled synchronization: checking for new videos...',
|
||||
0.1,
|
||||
None
|
||||
)
|
||||
|
||||
# Sync subscribed playlists/channels
|
||||
log.info("Sync - checking videos")
|
||||
@ -117,14 +127,32 @@ def synchronize():
|
||||
__check_new_videos_sub(subscription, yt_api)
|
||||
__detect_deleted(subscription)
|
||||
|
||||
notification_manager.notify_status_operation_progress(
|
||||
OPERATION_ID_SYNCHRONIZE,
|
||||
'Running scheduled synchronization: enqueueing videos to download...',
|
||||
0.5,
|
||||
None
|
||||
)
|
||||
|
||||
log.info("Sync - checking for videos to download")
|
||||
downloader_process_all()
|
||||
|
||||
notification_manager.notify_status_operation_progress(
|
||||
OPERATION_ID_SYNCHRONIZE,
|
||||
'Running scheduled synchronization: fetching thumbnails...',
|
||||
0.7,
|
||||
None
|
||||
)
|
||||
|
||||
log.info("Sync - fetching missing thumbnails")
|
||||
__fetch_thumbnails()
|
||||
|
||||
log.info("Synchronization finished.")
|
||||
notification_manager.notify_status_update(f'Synchronization finished for all subscriptions.')
|
||||
notification_manager.notify_status_operation_ended(
|
||||
OPERATION_ID_SYNCHRONIZE,
|
||||
'Synchronization finished.',
|
||||
None
|
||||
)
|
||||
|
||||
finally:
|
||||
__lock.release()
|
||||
|
@ -14,6 +14,8 @@ __NEXT_ID = 0
|
||||
__LOCK = Lock()
|
||||
|
||||
|
||||
OPERATION_ID_SYNCHRONIZE = 1
|
||||
|
||||
# Messages enum
|
||||
class Messages:
|
||||
STATUS_UPDATE = 'st-up'
|
||||
|
@ -126,4 +126,7 @@
|
||||
padding: 0.15rem 0.4rem;
|
||||
font-size: 14pt; }
|
||||
|
||||
.status-timestamp {
|
||||
margin-right: 0.25rem; }
|
||||
|
||||
/*# sourceMappingURL=style.css.map */
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": 3,
|
||||
"mappings": "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",
|
||||
"mappings": "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",
|
||||
"sources": ["style.scss"],
|
||||
"names": [],
|
||||
"file": "style.css"
|
||||
|
@ -156,4 +156,8 @@ $accent-color: #007bff;
|
||||
padding: 0.15rem 0.4rem;
|
||||
font-size: 14pt;
|
||||
}
|
||||
}
|
||||
|
||||
.status-timestamp {
|
||||
margin-right: 0.25rem;
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
<div class="video-gallery container-fluid">
|
||||
<div class="row">
|
||||
{% for video in videos %}
|
||||
<div class="card-wrapper col-12 col-sm-6 col-lg-4 col-xl-3 d-flex align-items-stretch">
|
||||
<div class="card-wrapper d-flex align-items-stretch" style="width: 18rem;">
|
||||
<div class="card mx-auto">
|
||||
<img class="card-img-top" src="{{ video.icon_best }}" alt="Thumbnail">
|
||||
<div class="card-body">
|
||||
|
@ -1,3 +1,11 @@
|
||||
function zeroFill(number, width) {
|
||||
width -= number.toString().length;
|
||||
if ( width > 0 ) {
|
||||
return new Array( width + (/\./.test( number ) ? 2 : 1) ).join( '0' ) + number;
|
||||
}
|
||||
return number + ""; // always return a string
|
||||
}
|
||||
|
||||
class AjaxModal
|
||||
{
|
||||
constructor(url)
|
||||
|
@ -179,6 +179,32 @@ function videos_Submit(e)
|
||||
/// Notifications
|
||||
///
|
||||
const NOTIFICATION_INTERVAL = 1000;
|
||||
const STATUS_UPDATE = 'st-up';
|
||||
const STATUS_OPERATION_PROGRESS = 'st-op-prog';
|
||||
const STATUS_OPERATION_END = 'st-op-end';
|
||||
const OPERATION_LIST = {};
|
||||
|
||||
function notifications_update_progress_bar() {
|
||||
|
||||
var count = 0;
|
||||
var percent = 0;
|
||||
|
||||
for(op in OPERATION_LIST) {
|
||||
count++;
|
||||
percent += OPERATION_LIST[op];
|
||||
}
|
||||
|
||||
let progress = $('#status-progress');
|
||||
if (count > 0) {
|
||||
progress.removeClass('invisible');
|
||||
let bar = progress.find('.progress-bar');
|
||||
bar.width(percent * 100 + '%');
|
||||
bar.text(count + ' operations in progress');
|
||||
}
|
||||
else {
|
||||
progress.addClass('invisible');
|
||||
}
|
||||
}
|
||||
|
||||
function get_and_process_notifications()
|
||||
{
|
||||
@ -190,9 +216,23 @@ function get_and_process_notifications()
|
||||
let dt = new Date(entry.time);
|
||||
|
||||
// Status update
|
||||
if (entry.msg === 'st-up') {
|
||||
if (entry.msg === STATUS_UPDATE) {
|
||||
let txt = `<span class="status-timestamp">${dt.getHours()}:${zeroFill(dt.getMinutes(), 2)}</span>${entry.status}`;
|
||||
$('#status-message').html(txt);
|
||||
}
|
||||
else if (entry.msg === STATUS_OPERATION_PROGRESS) {
|
||||
let txt = `<span class="status-timestamp">${dt.getHours()}:${zeroFill(dt.getMinutes(), 2)}</span>${entry.status}`;
|
||||
$('#status-message').html(txt);
|
||||
|
||||
OPERATION_LIST[entry.operation] = entry.progress;
|
||||
notifications_update_progress_bar();
|
||||
}
|
||||
else if (entry.msg === STATUS_OPERATION_END) {
|
||||
let txt = `<span class="status-timestamp">${dt.getHours()}:${dt.getMinutes()}</span>${entry.status}`;
|
||||
$('#status-message').html(txt);
|
||||
|
||||
delete OPERATION_LIST[entry.operation];
|
||||
notifications_update_progress_bar();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -65,11 +65,15 @@
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
<footer id="main_footer" class="footer bg-light">
|
||||
<span id="status-message" class="ml-auto text-muted">Last synchronized: just now</span>
|
||||
<footer id="main_footer" class="footer bg-light row">
|
||||
<button id="btn_sync_now" class="btn btn-sm btn-light" title="Synchronize now!">
|
||||
<span class="typcn typcn-arrow-sync" aria-hidden="true"></span>
|
||||
</button>
|
||||
<span id="status-message" class="text-muted"></span>
|
||||
<div id="status-progress" class="progress my-2 ml-auto invisible" style="width: 15rem">
|
||||
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 25%" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
|
||||
<script src="{% static 'YtManagerApp/import/jquery/jquery-3.3.1.min.js' %}"></script>
|
||||
|
Loading…
Reference in New Issue
Block a user