'use strict'; (() => { const post_ajax = (url, data) => { const loading = document.getElementById('loading'); if (loading) { loading.style.display = 'block'; } return fetch(`/${package_name}/ajax${url}`, { method: 'POST', cache: 'no-cache', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', }, body: new URLSearchParams(data), }) .then((response) => response.json()) .then((ret) => { if (ret.msg) { notify(ret.msg, ret.ret); } return ret; }) .catch(() => { notify('요청 실패', 'danger'); }) .finally(() => { if (loading) { loading.style.display = 'none'; } }); }; const all_stop_btn = document.getElementById('all_stop_btn'); const list_tbody = document.getElementById('list_tbody'); const get_item = (data) => { let str = `${data.index + 1}`; str += `${data.plugin}`; str += `${data.start_time}`; str += `${data.extractor}`; str += `${data.title}`; // Status color mapping let status_class = 'badge-secondary'; if (data.status_str === 'COMPLETED') status_class = 'badge-success'; else if (data.status_str === 'DOWNLOADING') status_class = 'badge-primary'; else if (data.status_str === 'ERROR') status_class = 'badge-danger'; str += `${data.status_ko}`; let visi = 'hidden'; if (parseInt(data.percent) > 0 && data.status_str !== 'STOP') { visi = 'visible'; } str += `
${data.percent}%
`; str += `${data.download_time}`; str += ''; if ( data.status_str === 'START' || data.status_str === 'DOWNLOADING' || data.status_str === 'FINISHED' ) { str += ``; } str += ''; return str; }; const info_html = (left, right, option) => { if (!right) return ''; let str = '
'; const link = left === 'URL' || left === '업로더'; str += '
'; str += `${left}`; str += '
'; str += '
'; str += '
'; if (link) { str += ``; } str += right; if (link) { str += ''; } str += '
'; return str; }; const get_detail = (data) => { let str = '
'; str += info_html('URL', data.url, data.url); str += info_html('업로더', data.uploader, data.uploader_url); str += info_html('임시폴더', data.temp_path); str += info_html('저장폴더', data.save_path); str += info_html('종료시간', data.end_time); if (data.status_str === 'DOWNLOADING') { str += '
'; str += '
실시간 다운로드 정보
'; str += info_html('파일명', data.filename); str += info_html( '현재 진행량', `${data.percent}% (${data.downloaded_bytes_str} / ${data.total_bytes_str})` ); str += info_html('남은 시간', `${data.eta}초`); str += info_html('다운 속도', `${data.speed_str}`); str += '
'; } str += '
'; return str; }; const make_item = (data) => { let str = ``; str += get_item(data); str += ''; str += ``; str += ''; str += `
`; str += get_detail(data); str += '
'; str += ''; str += ''; return str; }; const status_html = (data) => { document.getElementById(`item_${data.index}`).innerHTML = get_item(data); document.getElementById(`detail_${data.index}`).innerHTML = get_detail(data); }; // 소켓 const socket = io.connect(`${location.origin}/${package_name}`); socket.on('add', (data) => { list_tbody.innerHTML += make_item(data); }); socket.on('status', (data) => { status_html(data); }); const reload_list = async () => { const { data } = await post_ajax('/basic/list'); list_tbody.innerHTML = data.map((item) => make_item(item)).join(''); }; // 전체 중지 all_stop_btn.addEventListener('click', (event) => { event.preventDefault(); post_ajax('/basic/all_stop').then(reload_list); }); // 중지 list_tbody.addEventListener('click', (event) => { event.preventDefault(); const target = event.target; if (!target.classList.contains('youtubeDl-stop')) { return; } post_ajax('/basic/stop', { index: target.dataset.index, }).then(reload_list); }); // 목록 불러오기 reload_list(); })();