/* * This file is part of nzbget. See . * * Copyright (C) 2012-2019 Andrey Prygunkov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* * In this module: * 1) Download edit dialog; * 2) Download multi edit dialog (edit multiple items); * 3) Download merge dialog; * 4) Download split dialog; * 5) History edit dialog. */ /*** DOWNLOAD EDIT DIALOG ************************************************************/ var DownloadsEditDialog = (new function($) { 'use strict'; // Controls var $DownloadsEditDialog; var $DownloadsFileTable; var $DownloadsEdit_ParamData; var $ServStatsTable; // State var curGroup; var notification = null; var postParams = []; var lastPage; var lastFullscreen; var logFilled; var files; var refreshTimer = 0; var showing; var oldCategory; this.init = function() { $DownloadsEditDialog = $('#DownloadsEditDialog'); $DownloadsEdit_ParamData = $('#DownloadsEdit_ParamData'); $('#DownloadsEdit_Save').click(saveChanges); $('#DownloadsEdit_Actions').click(itemActions); $('#DownloadsEdit_Param, #DownloadsEdit_Log, #DownloadsEdit_File, #DownloadsEdit_Dupe').click(tabClick); $('#DownloadsEdit_Back').click(backClick); $('#DownloadsEdit_Category').change(categoryChange); LogTab.init('Downloads'); $DownloadsFileTable = $('#DownloadsEdit_FileTable'); $DownloadsFileTable.fasttable( { filterInput: '#DownloadsEdit_FileTable_filter', pagerContainer: '#DownloadsEdit_FileTable_pager', rowSelect: UISettings.rowSelect, pageSize: 10000, renderCellCallback: fileTableRenderCellCallback }); $ServStatsTable = $('#DownloadsEdit_ServStatsTable'); $ServStatsTable.fasttable( { filterInput: '#DownloadsEdit_ServStatsTable_filter', pagerContainer: '#DownloadsEdit_ServStatsTable_pager', pageSize: 100, maxPages: 3, renderCellCallback: EditUI.servStatsTableRenderCellCallback }); $DownloadsEditDialog.on('hidden', function() { // cleanup LogTab.reset('Downloads'); $DownloadsFileTable.fasttable('update', []); $DownloadsEdit_ParamData.empty(); clearTimeout(refreshTimer); // resume updates Refresher.resume(); }); TabDialog.extend($DownloadsEditDialog); if (UISettings.setFocus) { $DownloadsEditDialog.on('shown', function() { if ($('#DownloadsEdit_NZBName').is(":visible")) { $('#DownloadsEdit_NZBName').focus(); } }); } } this.showModal = function(nzbid, allGroups, area) { var group = null; // find Group object for (var i=0; i 0 ? Util.round0(group.SuccessArticles * 100.0 / (group.SuccessArticles + group.FailedArticles)) + '%' : '--'; if (group.FailedArticles > 0 && completion === '100%') { completion = '99.9%'; } var table = ''; //table += 'Age' + age + ''; table += 'Total' + size + ''; table += 'Paused' + pausedSize + ''; table += 'Unpaused' + remaining + ''; //table += 'Size (total/remaining/paused)4.10 / 4.10 / 0.00 GB'; //table += 'Active downloads' + group.ActiveDownloads + ''; //table += 'Estimated time' + estimated + ''; table += 'Health (critical/current)' + Math.floor(group.CriticalHealth / 10) + '% / ' + Math.floor(group.Health / 10) + '%'; table += 'Files (total/remaining/pars)' + group.FileCount + ' / ' + group.RemainingFileCount + ' / ' + group.RemainingParCount + ''; table += '' + (group.ServerStats.length > 0 ? '' : '') + 'Articles (total/completion)' + (group.ServerStats.length > 0 ? ' ' : '') + '' + group.TotalArticles + ' / ' + completion + ''; $('#DownloadsEdit_Statistics').html(table); $('#DownloadsEdit_ServStats').click(tabClick); EditUI.fillServStats($ServStatsTable, group); $ServStatsTable.fasttable('setCurPage', 1); $('#DownloadsEdit_Title').html(Util.formatNZBName(group.NZBName) + (group.Kind === 'URL' ? ' URL' : '')); $('#DownloadsEdit_NZBName').attr('value', group.NZBName); $('#DownloadsEdit_NZBName').attr('readonly', group.postprocess); $('#DownloadsEdit_URL').attr('value', group.URL); // Priority var v = $('#DownloadsEdit_Priority'); DownloadsUI.fillPriorityCombo(v); v.val(group.MaxPriority); if (v.val() != group.MaxPriority) { v.append(''); } v.attr('disabled', 'disabled'); // Category v = $('#DownloadsEdit_Category'); DownloadsUI.fillCategoryCombo(v); v.val(group.Category); if (v.val() != group.Category) { v.append($('').text(group.Category)); } // duplicate settings $('#DownloadsEdit_DupeKey').val(group.DupeKey); $('#DownloadsEdit_DupeScore').val(group.DupeScore); $('#DownloadsEdit_DupeMode').val(group.DupeMode); $DownloadsFileTable.fasttable('update', []); var postParamConfig = ParamTab.createPostParamConfig(); Util.show('#DownloadsEdit_NZBNameReadonly', group.postprocess); Util.show('#DownloadsEdit_Save', !group.postprocess); Util.show('#DownloadsEdit_StatisticsGroup', group.Kind === 'NZB'); Util.show('#DownloadsEdit_File', group.Kind === 'NZB'); Util.show('#DownloadsEdit_URLGroup', group.Kind === 'URL'); $('#DownloadsEdit_CategoryGroup').toggleClass('control-group-last', group.Kind === 'URL'); var dupeCheck = Options.option('DupeCheck') === 'yes'; Util.show('#DownloadsEdit_Dupe', dupeCheck); var postParam = postParamConfig[0].options.length > 0 && group.Kind === 'NZB'; var postLog = group.MessageCount > 0; Util.show('#DownloadsEdit_Param', postParam); Util.show('#DownloadsEdit_Log', postLog); if (group.postprocess) { $('#DownloadsEdit_NZBName').attr('disabled', 'disabled'); $('#DownloadsEdit_Priority').attr('disabled', 'disabled'); $('#DownloadsEdit_Category').attr('disabled', 'disabled'); $('#DownloadsEdit_Close').addClass('btn-primary'); $('#DownloadsEdit_Close').text('Close'); } else { $('#DownloadsEdit_NZBName').removeAttr('disabled'); $('#DownloadsEdit_Priority').removeAttr('disabled'); $('#DownloadsEdit_Category').removeAttr('disabled'); $('#DownloadsEdit_Close').removeClass('btn-primary'); $('#DownloadsEdit_Close').text('Cancel'); } if (postParam) { postParams = ParamTab.buildPostParamTab($DownloadsEdit_ParamData, postParamConfig, curGroup.Parameters); } enableAllButtons(); $('#DownloadsEdit_GeneralTab').show(); $('#DownloadsEdit_ParamTab').hide(); $('#DownloadsEdit_ServStatsTab').hide(); $('#DownloadsEdit_LogTab').hide(); $('#DownloadsEdit_FileTab').hide(); $('#DownloadsEdit_DupeTab').hide(); $('#DownloadsEdit_Back').hide(); $('#DownloadsEdit_BackSpace').show(); $DownloadsEditDialog.restoreTab(); $('#DownloadsEdit_FileTable_filter').val(''); $DownloadsFileTable.fasttable('setCurPage', 1); $DownloadsFileTable.fasttable('applyFilter', ''); LogTab.reset('Downloads'); files = null; logFilled = false; notification = null; oldCategory = curGroup.Category; if (area === 'backup') { showing = true; $('#DownloadsEdit_ServStats').trigger('click'); } showing = false; $DownloadsEditDialog.modal({backdrop: 'static'}); } function completed() { $DownloadsEditDialog.modal('hide'); Refresher.update(); if (notification) { PopupNotification.show(notification); notification = null; } } function tabClick(e) { e.preventDefault(); $('#DownloadsEdit_Back').fadeIn(showing ? 0 : 500); $('#DownloadsEdit_BackSpace').hide(); var tab = '#' + $(this).attr('data-tab'); lastPage = $(tab); lastFullscreen = ($(this).attr('data-fullscreen') === 'true') && !UISettings.miniTheme; $('#DownloadsEdit_FileBlock').removeClass('modal-inner-scroll'); $('#DownloadsEdit_FileBlock').css('top', ''); if (UISettings.miniTheme && files === null) { $('#DownloadsEdit_FileBlock').css('min-height', $DownloadsEditDialog.height()); } if (UISettings.miniTheme && !logFilled) { $('#DownloadsEdit_LogBlock').css('min-height', $DownloadsEditDialog.height()); } $DownloadsEditDialog.switchTab($('#DownloadsEdit_GeneralTab'), lastPage, e.shiftKey || !UISettings.slideAnimation || showing ? 0 : 500, {fullscreen: lastFullscreen, mini: UISettings.miniTheme, complete: function() { if (!UISettings.miniTheme) { $('#DownloadsEdit_FileBlock').css('top', $('#DownloadsEdit_FileBlock').position().top); $('#DownloadsEdit_FileBlock').addClass('modal-inner-scroll'); } else { $('#DownloadsEdit_FileBlock').css('min-height', ''); $('#DownloadsEdit_LogBlock').css('min-height', ''); } }}); if (tab === '#DownloadsEdit_LogTab' && !logFilled && (curGroup.postprocess || curGroup.MessageCount > 0)) { LogTab.fill('Downloads', curGroup); logFilled = true; } if (tab === '#DownloadsEdit_FileTab' && files === null) { fillFiles(); } if (tab === '#DownloadsEdit_ServStatsTab') { scheduleRefresh(); } } function backClick(e) { e.preventDefault(); $('#DownloadsEdit_Back').fadeOut(500, function() { $('#DownloadsEdit_BackSpace').show(); }); $('#DownloadsEdit_FileBlock').removeClass('modal-inner-scroll'); $('#DownloadsEdit_FileBlock').css('top', ''); $DownloadsEditDialog.switchTab(lastPage, $('#DownloadsEdit_GeneralTab'), e.shiftKey || !UISettings.slideAnimation ? 0 : 500, {fullscreen: lastFullscreen, mini: UISettings.miniTheme, back: true}); clearTimeout(refreshTimer); } function disableAllButtons() { $('#DownloadsEditDialog .modal-footer .btn').attr('disabled', 'disabled'); setTimeout(function() { $('#DownloadsEdit_Transmit').show(); }, 500); } function enableAllButtons() { $('#DownloadsEditDialog .modal-footer .btn').removeAttr('disabled'); $('#DownloadsEdit_Transmit').hide(); } function saveChanges(e) { e.preventDefault(); disableAllButtons(); notification = null; saveName(); } function saveName() { var name = $('#DownloadsEdit_NZBName').val(); name !== curGroup.NZBName && !curGroup.postprocess ? RPC.call('editqueue', ['GroupSetName', name, [curGroup.NZBID]], function() { notification = '#Notif_Downloads_Saved'; savePriority(); }) :savePriority(); } function savePriority() { var priority = parseInt($('#DownloadsEdit_Priority').val()); priority !== curGroup.MaxPriority ? RPC.call('editqueue', ['GroupSetPriority', '' + priority, [curGroup.NZBID]], function() { notification = '#Notif_Downloads_Saved'; saveCategory(); }) : saveCategory(); } function saveCategory() { var category = $('#DownloadsEdit_Category').val(); category !== curGroup.Category ? RPC.call('editqueue', ['GroupSetCategory', category, [curGroup.NZBID]], function() { notification = '#Notif_Downloads_Saved'; saveDupeKey(); }) : saveDupeKey(); } function itemActions(e) { e.preventDefault(); e.stopPropagation(); var elem = $('#DownloadsEdit_Actions').parent(); DownloadsActionsMenu.showPopupMenu(curGroup, 'top', { left: elem.offset().left, top: elem.offset().top - 1, width: elem.width(), height: elem.height() + 2 }, function(_notification) { disableAllButtons(); notification = _notification; }, completed); } function categoryChange() { var category = $('#DownloadsEdit_Category').val(); ParamTab.reassignParams(postParams, oldCategory, category); oldCategory = category; } /*** TAB: POST-PROCESSING PARAMETERS **************************************************/ function saveParam() { if (curGroup.Kind === 'URL') { completed(); return; } var paramList = ParamTab.prepareParamRequest(postParams); saveNextParam(paramList); } function saveNextParam(paramList) { if (paramList.length > 0) { RPC.call('editqueue', ['GroupSetParameter', paramList[0], [curGroup.NZBID]], function() { notification = '#Notif_Downloads_Saved'; paramList.shift(); saveNextParam(paramList); }) } else { saveFiles(); } } /*** TAB: DUPLICATE SETTINGS **************************************************/ function saveDupeKey() { var value = $('#DownloadsEdit_DupeKey').val(); value !== curGroup.DupeKey ? RPC.call('editqueue', ['GroupSetDupeKey', value, [curGroup.NZBID]], function() { notification = '#Notif_Downloads_Saved'; saveDupeScore(); }) :saveDupeScore(); } function saveDupeScore() { var value = $('#DownloadsEdit_DupeScore').val(); value != curGroup.DupeScore ? RPC.call('editqueue', ['GroupSetDupeScore', value, [curGroup.NZBID]], function() { notification = '#Notif_Downloads_Saved'; saveDupeMode(); }) :saveDupeMode(); } function saveDupeMode() { var value = $('#DownloadsEdit_DupeMode').val(); value !== curGroup.DupeMode ? RPC.call('editqueue', ['GroupSetDupeMode', value, [curGroup.NZBID]], function() { notification = '#Notif_Downloads_Saved'; saveParam(); }) :saveParam(); } /*** TAB: FILES *************************************************************************/ function fillFiles() { $('.loading-block', $DownloadsEditDialog).show(); RPC.call('listfiles', [0, 0, curGroup.NZBID], filesLoaded); } function filesLoaded(fileArr) { $('.loading-block', $DownloadsEditDialog).hide(); files = fileArr; var data = []; for (var i=0; i < files.length; i++) { var file = files[i]; if (!file.status) { file.status = file.Paused ? (file.ActiveDownloads > 0 ? 'pausing' : 'paused') : (file.ActiveDownloads > 0 ? 'downloading' : 'queued'); } var FileSizeMB = (file.FileSizeHi * 4096) + (file.FileSizeLo / 1024 / 1024); var RemainingSizeMB = (file.RemainingSizeHi * 4096) + (file.RemainingSizeLo / 1024 / 1024); var age = Util.formatAge(file.PostTime + UISettings.timeZoneCorrection*60*60); var size = Util.formatSizeMB(FileSizeMB, file.FileSizeLo); if (FileSizeMB !== RemainingSizeMB || file.FileSizeLo !== file.RemainingSizeLo) { size = '(' + Util.round0((file.FileSizeHi > 0 ? RemainingSizeMB / FileSizeMB : file.RemainingSizeLo / file.FileSizeLo) * 100) + '%) ' + size; } var status; switch (file.status) { case 'downloading': case 'pausing': status = '' + file.status + ''; break; case 'paused': status = 'paused'; break; case 'queued': status = 'queued'; break; case 'deleted': status = 'deleted'; break; default: status = 'internal error(' + file.status + ')'; } var name = Util.textToHtml(file.Filename); var fields; if (!UISettings.miniTheme) { var info = name; fields = ['
', status, info, age, size]; } else { var info = '
' + name + '' + ' ' + (file.status === 'queued' ? '' : status); fields = [info]; } var item = { id: file.ID, file: file, fields: fields, data: { status: file.status, name: file.Filename, age: age, size: size, _search: true } }; data.push(item); } $DownloadsFileTable.fasttable('update', data); } function fileTableRenderCellCallback(cell, index, item) { if (index > 2) { cell.className = 'text-right'; } } this.editActionClick = function(action) { if (files.length == 0) { return; } var checkedRows = $DownloadsFileTable.fasttable('checkedRows'); var checkedCount = $DownloadsFileTable.fasttable('checkedCount'); if (checkedCount === 0) { PopupNotification.show('#Notif_Edit_Select'); return; } for (var i = 0; i < files.length; i++) { var file = files[i]; file.moved = false; } var editIDList = []; var splitError = false; for (var i = 0; i < files.length; i++) { var n = i; if (action === 'down' || action === 'top') { // iterate backwards in the file list n = files.length-1-i; } var file = files[n]; if (checkedRows[file.ID]) { editIDList.push(file.ID); switch (action) { case 'pause': file.status = 'paused'; file.editAction = action; break; case 'resume': file.status = 'queued'; file.editAction = action; break; case 'delete': file.status = 'deleted'; file.editAction = action; break; case 'top': if (!file.moved) { files.splice(n, 1); files.unshift(file); file.moved = true; file.editMoved = true; i--; } break; case 'up': if (!file.moved && i > 0) { files.splice(i, 1); files.splice(i-1, 0, file); file.moved = true; file.editMoved = true; } break; case 'down': if (!file.moved && i > 0) { files.splice(n, 1); files.splice(n+1, 0, file); file.moved = true; file.editMoved = true; } break; case 'bottom': if (!file.moved) { files.splice(i, 1); files.push(file); file.moved = true; file.editMoved = true; i--; } break; case 'split': if (file.ActiveDownloads > 0 || file.Progress > 0) { splitError = true; } break; } } } if (action === 'split') { if (splitError) { PopupNotification.show('#Notif_Downloads_SplitNotPossible'); } else { DownloadsSplitDialog.showModal(curGroup, editIDList); } } filesLoaded(files); } function saveFilesActions(actions, commands) { if (actions.length === 0 || !files || files.length === 0) { saveFileOrder(); return; } var action = actions.shift(); var command = commands.shift(); var IDs = []; for (var i = 0; i < files.length; i++) { var file = files[i]; if (file.editAction === action) { IDs.push(file.ID); } } if (IDs.length > 0) { RPC.call('editqueue', [command, '', IDs], function() { notification = '#Notif_Downloads_Saved'; saveFilesActions(actions, commands); }) } else { saveFilesActions(actions, commands); } } function saveFiles() { saveFilesActions(['pause', 'resume', 'delete'], ['FilePause', 'FileResume', 'FileDelete']); } function saveFileOrder() { if (!files || files.length === 0) { completed(); return; } var IDs = []; var hasMovedFiles = false; for (var i = 0; i < files.length; i++) { var file = files[i]; IDs.push(file.ID); hasMovedFiles |= file.editMoved; } if (hasMovedFiles) { RPC.call('editqueue', ['FileReorder', '', IDs], function() { notification = '#Notif_Downloads_Saved'; completed(); }) } else { completed(); } } /*** TAB: PER-SERVER STATUSTICS *****************************************************************/ function scheduleRefresh() { refreshTimer = setTimeout(updateServStats, UISettings.refreshInterval * 1000); } function updateServStats() { RPC.call('listgroups', [], groups_loaded); } function groups_loaded(groups) { for (var i=0, il=groups.length; i < il; i++) { var group = groups[i]; if (group.NZBID === curGroup.NZBID) { curGroup.ServerStats = group.ServerStats; EditUI.fillServStats($ServStatsTable, group); scheduleRefresh(); break; } } } }(jQuery)); /*** COMMON FUNCTIONS FOR EDIT DIALOGS ************************************************************/ var EditUI = (new function($) { 'use strict' /*** TAB: SERVER STATISTICS **************************************************/ this.fillServStats = function(table, editItem) { var data = []; for (var i=0; i < Status.status.NewsServers.length; i++) { var server = Status.status.NewsServers[i]; var name = Options.option('Server' + server.ID + '.Name'); if (name === null || name === '') { var host = Options.option('Server' + server.ID + '.Host'); var port = Options.option('Server' + server.ID + '.Port'); name = (host === null ? '' : host) + ':' + (port === null ? '119' : port); } var articles = '--'; var artquota = '--'; var success = '--'; var failures = '--'; for (var j=0; j < editItem.ServerStats.length; j++) { var stat = editItem.ServerStats[j]; if (stat.ServerID === server.ID && stat.SuccessArticles + stat.FailedArticles > 0) { articles = stat.SuccessArticles + stat.FailedArticles; artquota = Util.round0(articles * 100.0 / (editItem.SuccessArticles + editItem.FailedArticles)) + '%'; success = Util.round0(stat.SuccessArticles * 100.0 / articles) + '%'; failures = Util.round0(stat.FailedArticles * 100.0 / articles) + '%'; if (stat.FailedArticles > 0 && failures === '0%') { success = '99.9%'; failures = '0.1%'; } success = '' + success + ''; failures = '' + failures + ''; break; } } var fields = [server.ID + '. ' + name, articles, artquota, success, failures]; var item = { id: server.ID, fields: fields, }; data.push(item); } table.fasttable('update', data); } this.servStatsTableRenderCellCallback = function (cell, index, item) { if (index > 0) { cell.className = 'text-right'; } } }(jQuery)); /*** PARAM TAB FOR EDIT DIALOGS ************************************************************/ var ParamTab = (new function($) { 'use strict' this.buildPostParamTab = function(configData, postParamConfig, parameters) { var postParams = $.extend(true, [], postParamConfig); Options.mergeValues(postParams, parameters); var content = Config.buildOptionsContent(postParams[0]); configData.empty(); configData.append(content); configData.addClass('retain-margin'); var lastClass = ''; var lastDiv = null; for (var i=0; i < configData.children().length; i++) { var div = $(configData.children()[i]); var divClass = div.attr('class'); if (divClass != lastClass && lastClass != '') { lastDiv.addClass('wants-divider'); } lastDiv = div; lastClass = divClass; } return postParams; } this.createPostParamConfig = function() { var postParamConfig = Options.postParamConfig; defineBuiltinParams(postParamConfig); return postParamConfig; } function defineBuiltinParams(postParamConfig) { if (postParamConfig.length == 0) { postParamConfig.push({category: 'P', postparam: true, options: []}); } if (!Options.findOption(postParamConfig[0].options, '*Unpack:')) { postParamConfig[0].options.unshift({name: '*Unpack:Password', value: '', defvalue: '', select: [], caption: 'Password', sectionId: '_Unpack_', description: 'Unpack-password for encrypted archives.'}); postParamConfig[0].options.unshift({name: '*Unpack:', value: '', defvalue: 'yes', select: ['yes', 'no'], caption: 'Unpack', sectionId: '_Unpack_', description: 'Unpack rar and 7-zip archives.'}); } } this.prepareParamRequest = function(postParams) { var request = []; for (var i=0; i < postParams.length; i++) { var section = postParams[i]; for (var j=0; j < section.options.length; j++) { var option = section.options[j]; if (!option.template && !section.hidden) { var oldValue = option.value; var newValue = Config.getOptionValue(option); if (oldValue != newValue && !((oldValue === null || oldValue === '') && newValue === option.defvalue)) { var opt = option.name + '=' + newValue; request.push(opt); } } } } return request; } function buildCategoryScriptList(category) { var scriptList = []; for (var i=0; i < Options.categories.length; i++) { if (category === Options.categories[i]) { scriptList = Util.parseCommaList(Options.option('Category' + (i + 1) + '.Extensions')); if (scriptList.length === 0) { scriptList = Util.parseCommaList(Options.option('Extensions')); } if (Options.option('Category' + (i + 1) + '.Unpack') === 'yes') { scriptList.push('*Unpack'); } return scriptList; } } // empty category or category not found scriptList = Util.parseCommaList(Options.option('Extensions')); if (Options.option('Unpack') === 'yes') { scriptList.push('*Unpack'); } return scriptList; } this.reassignParams = function(postParams, oldCategory, newCategory) { var oldScriptList = buildCategoryScriptList(oldCategory); var newScriptList = buildCategoryScriptList(newCategory); for (var i=0; i < postParams.length; i++) { var section = postParams[i]; for (var j=0; j < section.options.length; j++) { var option = section.options[j]; if (!option.template && !section.hidden && option.name.substr(option.name.length - 1, 1) === ':') { var scriptName = option.name.substr(0, option.name.length-1); if (oldScriptList.indexOf(scriptName) > -1 && newScriptList.indexOf(scriptName) === -1) { Config.setOptionValue(option, 'no'); } else if (oldScriptList.indexOf(scriptName) === -1 && newScriptList.indexOf(scriptName) > -1) { Config.setOptionValue(option, 'yes'); } } } } } }(jQuery)); /*** LOG TAB FOR EDIT DIALOGS ************************************************************/ var LogTab = (new function($) { 'use strict' var curLog; var curItem; this.init = function(name) { var recordsPerPage = UISettings.read('ItemLogRecordsPerPage', 10); $('#' + name + 'LogRecordsPerPage').val(recordsPerPage); var $LogTable = $('#' + name + 'Edit_LogTable'); $LogTable.fasttable( { filterInput: '#' + name + 'Edit_LogTable_filter', pagerContainer: '#' + name + 'Edit_LogTable_pager', pageSize: recordsPerPage, maxPages: 3, renderCellCallback: logTableRenderCellCallback }); } this.reset = function(name) { var $LogTable = $('#' + name + 'Edit_LogTable'); $LogTable.fasttable('update', []); $LogTable.fasttable('setCurPage', 1); $LogTable.fasttable('applyFilter', ''); $('#' + name + 'Edit_LogTable_filter').val(''); } this.fill = function(name, item) { curItem = item; function logLoaded(log) { curLog = log; $('#' + name + 'EditDialog .loading-block').hide(); var $LogTable = $('#' + name + 'Edit_LogTable'); var data = []; for (var i=0; i < log.length; i++) { var message = log[i]; var kind; switch (message.Kind) { case 'INFO': kind = 'info'; break; case 'DETAIL': kind = 'detail'; break; case 'WARNING': kind = 'warning'; break; case 'ERROR': kind = 'error'; break; case 'DEBUG': kind = 'debug'; break; } var text = Util.textToHtml(message.Text); var time = Util.formatDateTime(message.Time + UISettings.timeZoneCorrection*60*60); var fields; if (!UISettings.miniTheme) { fields = [kind, time, text]; } else { var info = kind + ' ' + time + ' ' + text; fields = [info]; } var item = { id: message, fields: fields, data: { kind: message.Kind, time: time, text: message.Text, _search: true } }; data.unshift(item); } $LogTable.fasttable('update', data); } var recordsPerPage = UISettings.read('ItemLogRecordsPerPage', 10); $('#' + name + 'LogRecordsPerPage').val(recordsPerPage); $('#' + name + 'EditDialog .loading-block').show(); RPC.call('loadlog', [item.NZBID, 0, 10000], logLoaded); } function logTableRenderCellCallback(cell, index, item) { if (index === 0) { cell.width = '65px'; } } this.recordsPerPageChange = function(name) { var val = $('#' + name + 'LogRecordsPerPage').val(); UISettings.write('ItemLogRecordsPerPage', val); var $LogTable = $('#' + name + 'Edit_LogTable'); $LogTable.fasttable('setPageSize', val); } this.export = function() { var filename = curItem.NZBName + '.log'; var logstr = ''; for (var i=0; i < curLog.length; i++) { var message = curLog[i]; var time = Util.formatDateTime(message.Time + UISettings.timeZoneCorrection*60*60); logstr += time + '\t' + message.Kind + '\t' + message.Text + '\n'; } if (!Util.saveToLocalFile(logstr, "text/plain;charset=utf-8", filename)) { var queueDir = Options.option('QueueDir'); var pathSeparator = queueDir.indexOf('\\') > -1 ? '\\' : '/'; alert('Unfortunately your browser doesn\'t support access to local file system.\n\n' + 'The log of this nzb can be found in file "' + queueDir + pathSeparator + 'n' + curItem.NZBID + '.log"'); } } }(jQuery)); /*** DOWNLOAD MULTI EDIT DIALOG ************************************************************/ var DownloadsMultiDialog = (new function($) { 'use strict' // Controls var $DownloadsMultiDialog; // State var multiIDList; var notification = null; var oldPriority; var oldCategory; this.init = function() { $DownloadsMultiDialog = $('#DownloadsMultiDialog'); $('#DownloadsMulti_Save').click(saveChanges); $DownloadsMultiDialog.on('hidden', function () { Refresher.resume(); }); if (UISettings.setFocus) { $DownloadsMultiDialog.on('shown', function () { if ($('#DownloadsMulti_Priority').is(":visible")) { $('#DownloadsMulti_Priority').focus(); } }); } } this.showModal = function(nzbIdList, allGroups) { var groups = []; multiIDList = []; for (var i=0; i -1) { groups.push(gr); multiIDList.push(gr.NZBID); } } if (groups.length == 0) { return; } Refresher.pause(); var FileSizeMB = 0, FileSizeLo = 0; var RemainingSizeMB = 0, RemainingSizeLo = 0; var PausedSizeMB = 0, PausedSizeLo = 0; var FileCount = 0, RemainingFileCount = 0, RemainingParCount = 0; var paused = true; var Priority = groups[0].MaxPriority; var PriorityDiff = false; var Category = groups[0].Category; var CategoryDiff = false; for (var i=0; i 0 ? Util.formatTimeHMS((RemainingSizeMB-PausedSizeMB)*1024/(Status.status.DownloadRate/1024)) : ''); var table = ''; table += 'Total' + size + ''; table += 'Paused' + unpausedSize + ''; table += 'Unpaused' + remaining + ''; table += 'Estimated time' + estimated + ''; table += 'Files (total/remaining/pars)' + FileCount + ' / ' + RemainingFileCount + ' / ' + RemainingParCount + ''; $('#DownloadsMulti_Statistics').html(table); $('#DownloadsMulti_Title').text('Multiple records (' + groups.length + ')'); // Priority var v = $('#DownloadsMulti_Priority'); DownloadsUI.fillPriorityCombo(v); v.val(Priority); if (v.val() != Priority) { v.append(''); v.val(Priority); } if (PriorityDiff) { v.append(''); } oldPriority = v.val(); $('#DownloadsMulti_Priority').removeAttr('disabled'); // Category var v = $('#DownloadsMulti_Category'); DownloadsUI.fillCategoryCombo(v); v.val(Category); if (v.val() != Category) { v.append($('').text(Category)); v.val(Category); } if (CategoryDiff) { v.append(''); } oldCategory = v.val(); enableAllButtons(); $('#DownloadsMulti_GeneralTabLink').tab('show'); notification = null; $DownloadsMultiDialog.modal({backdrop: 'static'}); } function enableAllButtons() { $('#DownloadsMulti .modal-footer .btn').removeAttr('disabled'); $('#DownloadsMulti_Transmit').hide(); } function disableAllButtons() { $('#DownloadsMulti .modal-footer .btn').attr('disabled', 'disabled'); setTimeout(function() { $('#DownloadsMulti_Transmit').show(); }, 500); } function saveChanges(e) { e.preventDefault(); disableAllButtons(); savePriority(); } function savePriority() { var priority = $('#DownloadsMulti_Priority').val(); (priority !== oldPriority && priority !== '') ? RPC.call('editqueue', ['GroupSetPriority', priority, multiIDList], function() { notification = '#Notif_Downloads_Saved'; saveCategory(); }) : saveCategory(); } function saveCategory() { var category = $('#DownloadsMulti_Category').val(); (category !== oldCategory && category !== '') ? RPC.call('editqueue', ['GroupApplyCategory', category, multiIDList], function() { notification = '#Notif_Downloads_Saved'; completed(); }) : completed(); } function completed() { $DownloadsMultiDialog.modal('hide'); Refresher.update(); if (notification) { PopupNotification.show(notification); } } }(jQuery)); /*** DOWNLOAD MERGE DIALOG ************************************************************/ var DownloadsMergeDialog = (new function($) { 'use strict' // Controls var $DownloadsMergeDialog; // State var mergeEditIDList; this.init = function() { $DownloadsMergeDialog = $('#DownloadsMergeDialog'); $('#DownloadsMerge_Merge').click(merge); $DownloadsMergeDialog.on('hidden', function () { Refresher.resume(); }); if (UISettings.setFocus) { $DownloadsMergeDialog.on('shown', function () { $('#DownloadsMerge_Merge').focus(); }); } } this.showModal = function(nzbIdList, allGroups) { Refresher.pause(); mergeEditIDList = []; $('#DownloadsMerge_Files').empty(); for (var i = 0; i < allGroups.length; i++) { var group = allGroups[i]; if (nzbIdList.indexOf(group.NZBID) > -1) { mergeEditIDList.push(group.NZBID); var html = '
' + Util.formatNZBName(group.NZBName) + '
'; $('#DownloadsMerge_Files').append(html); } } $DownloadsMergeDialog.modal({backdrop: 'static'}); } function merge() { RPC.call('editqueue', ['GroupMerge', '', mergeEditIDList], completed); } function completed() { $DownloadsMergeDialog.modal('hide'); Refresher.update(); PopupNotification.show('#Notif_Downloads_Merged'); } }(jQuery)); /*** DOWNLOAD SPLIT DIALOG ************************************************************/ var DownloadsSplitDialog = (new function($) { 'use strict' // Controls var $DownloadsSplitDialog; // State var splitEditIDList; this.init = function() { $DownloadsSplitDialog = $('#DownloadsSplitDialog'); $('#DownloadsSplit_Split').click(split); $DownloadsSplitDialog.on('hidden', function () { Refresher.resume(); }); if (UISettings.setFocus) { $DownloadsSplitDialog.on('shown', function () { $('#DownloadsSplit_Merge').focus(); }); } } this.showModal = function(group, editIDList) { Refresher.pause(); splitEditIDList = editIDList; var groupName = group.NZBName + ' (' + editIDList[0] + (editIDList.length > 1 ? '-' + editIDList[editIDList.length-1] : '') + ')'; $('#DownloadsSplit_NZBName').attr('value', groupName); $DownloadsSplitDialog.modal({backdrop: 'static'}); } function split() { var groupName = $('#DownloadsSplit_NZBName').val(); RPC.call('editqueue', ['FileSplit', groupName, splitEditIDList], completed); } function completed(result) { $('#DownloadsEditDialog').modal('hide'); $DownloadsSplitDialog.modal('hide'); Refresher.update(); PopupNotification.show(result ? '#Notif_Downloads_Splitted' : '#Notif_Downloads_SplitError'); } }(jQuery)); /*** EDIT HISTORY DIALOG *************************************************************************/ var HistoryEditDialog = (new function($) { 'use strict' // Controls var $HistoryEditDialog; var $HistoryEdit_ParamData; var $ServStatsTable; // State var curHist; var notification = null; var postParams = []; var lastPage; var lastFullscreen; var saveCompleted; var logFilled; var showing; this.init = function() { $HistoryEditDialog = $('#HistoryEditDialog'); $HistoryEdit_ParamData = $('#HistoryEdit_ParamData'); $('#HistoryEdit_Save').click(saveChanges); $('#HistoryEdit_Actions').click(itemActions); $('#HistoryEdit_Param, #HistoryEdit_Dupe, #HistoryEdit_Log').click(tabClick); $('#HistoryEdit_Back').click(backClick); LogTab.init('History'); $ServStatsTable = $('#HistoryEdit_ServStatsTable'); $ServStatsTable.fasttable( { filterInput: '#HistoryEdit_ServStatsTable_filter', pagerContainer: '#HistoryEdit_ServStatsTable_pager', pageSize: 100, maxPages: 3, renderCellCallback: EditUI.servStatsTableRenderCellCallback }); $HistoryEditDialog.on('hidden', function () { $HistoryEdit_ParamData.empty(); LogTab.reset('History'); // resume updates Refresher.resume(); }); TabDialog.extend($HistoryEditDialog); } this.showModal = function(hist, area) { Refresher.pause(); curHist = hist; var status = ''; if (hist.Kind === 'NZB') { if (hist.DeleteStatus === '' || hist.DeleteStatus === 'HEALTH') { status = 'health: ' + Math.floor(hist.Health / 10) + '%'; } if (hist.MarkStatus !== 'NONE') { status += ' ' + buildStatus(hist.MarkStatus, 'Mark: '); } else if (hist.DeleteStatus === 'NONE') { var exParStatus = hist.ExParStatus === 'RECIPIENT' ? ' ' + '' + buildStatus(hist.ExParStatus, 'ExPar: ') + '' : hist.ExParStatus === 'DONOR' ? ' ' + '' + buildStatus(hist.ExParStatus, 'ExPar: ') + '' : ''; status += ' ' + buildStatus(hist.ParStatus, 'Par: ') + exParStatus + ' ' + (Options.option('Unpack') == 'yes' || hist.UnpackStatus != 'NONE' ? buildStatus(hist.UnpackStatus, 'Unpack: ') : '') + ' ' + (hist.MoveStatus === "FAILURE" ? buildStatus(hist.MoveStatus, 'Move: ') : ''); } else { status += ' ' + buildStatus('DELETED-' + hist.DeleteStatus, 'Delete: '); } for (var i=0; i' + (hist.Kind === 'DUP' ? 'hidden' : hist.Kind) + ''); } $('#HistoryEdit_NZBName').val(hist.Name); if (hist.Kind !== 'DUP') { // Category var v = $('#HistoryEdit_Category'); DownloadsUI.fillCategoryCombo(v); v.val(hist.Category); if (v.val() != hist.Category) { v.append($('').text(hist.Category)); } } if (hist.Kind === 'NZB') { $('#HistoryEdit_Path').val(hist.FinalDir !== '' ? hist.FinalDir : hist.DestDir); var size = Util.formatSizeMB(hist.FileSizeMB, hist.FileSizeLo); var completion = hist.SuccessArticles + hist.FailedArticles > 0 ? Util.round0(hist.SuccessArticles * 100.0 / (hist.SuccessArticles + hist.FailedArticles)) + '%' : '--'; if (hist.FailedArticles > 0 && completion === '100%') { completion = '99.9%'; } var table = ''; table += 'Total '+ '' + '' + size + ''; table += 'Files (total/remaining)' + hist.FileCount + ' / ' + hist.RemainingFileCount + ''; table += '' + (hist.ServerStats.length > 0 ? '' : '') + 'Articles (total/completion)' + (hist.ServerStats.length > 0 ? ' ' : '') + '' + hist.TotalArticles + ' / ' + completion + ''; $('#HistoryEdit_Statistics').html(table); $('#HistoryEdit_ServStats').click(tabClick); EditUI.fillServStats($ServStatsTable, hist); $ServStatsTable.fasttable('setCurPage', 1); $('#HistoryEdit_TimeStats').click(tabClick); fillTimeStats(); } $('#HistoryEdit_DupeKey').val(hist.DupeKey); $('#HistoryEdit_DupeScore').val(hist.DupeScore); $('#HistoryEdit_DupeMode').val(hist.DupeMode); $('#HistoryEdit_DupeBackup').prop('checked', hist.DeleteStatus === 'DUPE'); $('#HistoryEdit_DupeBackup').prop('disabled', !(hist.DeleteStatus === 'DUPE' || hist.DeleteStatus === 'MANUAL')); Util.show($('#HistoryEdit_DupeBackup').closest('.control-group'), hist.Kind === 'NZB'); $('#HistoryEdit_DupeMode').closest('.control-group').toggleClass('last-group', hist.Kind !== 'NZB'); Util.show('#HistoryEdit_PathGroup, #HistoryEdit_StatisticsGroup', hist.Kind === 'NZB'); Util.show('#HistoryEdit_CategoryGroup', hist.Kind !== 'DUP'); Util.show('#HistoryEdit_DupGroup', hist.Kind === 'DUP'); var dupeCheck = Options.option('DupeCheck') === 'yes'; Util.show('#HistoryEdit_Dupe', dupeCheck); $('#HistoryEdit_CategoryGroup').toggleClass('control-group-last', hist.Kind === 'URL'); Util.show('#HistoryEdit_URLGroup', hist.Kind === 'URL'); $('#HistoryEdit_URL').attr('value', hist.URL); var postParamConfig = ParamTab.createPostParamConfig(); var postParam = hist.Kind === 'NZB' && postParamConfig[0].options.length > 0; Util.show('#HistoryEdit_Param', postParam); if (postParam) { postParams = ParamTab.buildPostParamTab($HistoryEdit_ParamData, postParamConfig, curHist.Parameters); } var postLog = hist.MessageCount > 0; Util.show('#HistoryEdit_Log', postLog); enableAllButtons(); $('#HistoryEdit_GeneralTab').show(); $('#HistoryEdit_ParamTab').hide(); $('#HistoryEdit_ServStatsTab').hide(); $('#HistoryEdit_TimeStatsTab').hide(); $('#HistoryEdit_DupeTab').hide(); $('#HistoryEdit_LogTab').hide(); $('#HistoryEdit_Back').hide(); $('#HistoryEdit_BackSpace').show(); $HistoryEditDialog.restoreTab(); LogTab.reset('History'); logFilled = false; notification = null; if (area === 'backup') { showing = true; $('#HistoryEdit_ServStats').trigger('click'); } showing = false; $HistoryEditDialog.modal({backdrop: 'static'}); } function buildStatus(status, prefix) { switch (status) { case 'SUCCESS': case 'GOOD': case 'RECIPIENT': case 'DONOR': return '' + prefix + status + ''; case 'FAILURE': return '' + prefix + 'failure'; case 'BAD': return '' + prefix + status + ''; case 'REPAIR_POSSIBLE': return '' + prefix + 'repairable'; case 'MANUAL': // PAR-MANUAL case 'SPACE': case 'PASSWORD': return '' + prefix + status + ''; case 'DELETED-DUPE': case 'DELETED-MANUAL': case 'DELETED-COPY': case 'DELETED-GOOD': case 'DELETED-SUCCESS': return '' + prefix + status.substr(8).toLowerCase() + ''; case 'DELETED-HEALTH': return '' + prefix + 'health'; case 'DELETED-BAD': return '' + prefix + 'bad'; case 'DELETED-SCAN': return '' + prefix + 'scan'; case 'SCAN_SKIPPED': return '' + prefix + 'skipped'; case 'NONE': return '' + prefix + 'none'; default: return '' + prefix + status + ''; } } function fillTimeStats() { var hist = curHist; var downloaded = Util.formatSizeMB(hist.DownloadedSizeMB, hist.DownloadedSizeLo); var speed = hist.DownloadTimeSec > 0 ? Util.formatSpeed((hist.DownloadedSizeMB > 1024 ? hist.DownloadedSizeMB * 1024.0 * 1024.0 : hist.DownloadedSizeLo) / hist.DownloadTimeSec) : '--'; var table = ''; table += 'Downloaded size' + downloaded + ''; table += 'Download speed' + speed + ''; table += 'Total time' + Util.formatTimeHMS(hist.DownloadTimeSec + hist.PostTotalTimeSec) + ''; table += 'Download time' + Util.formatTimeHMS(hist.DownloadTimeSec) + ''; table += 'Verification time ' + Util.formatTimeHMS(hist.ParTimeSec - hist.RepairTimeSec) + ''; table += 'Repair time' + Util.formatTimeHMS(hist.RepairTimeSec) + ''; table += 'Unpack time' + Util.formatTimeHMS(hist.UnpackTimeSec) + ''; table += hist.ExtraParBlocks > 0 ? 'Received extra par-blocks' + hist.ExtraParBlocks + '' : hist.ExtraParBlocks < 0 ? 'Donated par-blocks' + - hist.ExtraParBlocks + '' : ''; $('#HistoryEdit_TimeStatsTable tbody').html(table); } function tabClick(e) { e.preventDefault(); $('#HistoryEdit_Back').fadeIn(showing ? 0 : 500); $('#HistoryEdit_BackSpace').hide(); var tab = '#' + $(this).attr('data-tab'); lastPage = $(tab); lastFullscreen = ($(this).attr('data-fullscreen') === 'true') && !UISettings.miniTheme; $HistoryEditDialog.switchTab($('#HistoryEdit_GeneralTab'), lastPage, e.shiftKey || !UISettings.slideAnimation || showing ? 0 : 500, {fullscreen: lastFullscreen, mini: UISettings.miniTheme}); if (tab === '#HistoryEdit_LogTab' && !logFilled && curHist.MessageCount > 0) { LogTab.fill('History', curHist); logFilled = true; } } function backClick(e) { e.preventDefault(); $('#HistoryEdit_Back').fadeOut(500, function() { $('#HistoryEdit_BackSpace').show(); }); $HistoryEditDialog.switchTab(lastPage, $('#HistoryEdit_GeneralTab'), e.shiftKey || !UISettings.slideAnimation ? 0 : 500, {fullscreen: lastFullscreen, mini: UISettings.miniTheme, back: true}); } function disableAllButtons() { $('#HistoryEditDialog .modal-footer .btn').attr('disabled', 'disabled'); setTimeout(function() { $('#HistoryEdit_Transmit').show(); }, 500); } function enableAllButtons() { $('#HistoryEditDialog .modal-footer .btn').removeAttr('disabled'); $('#HistoryEdit_Transmit').hide(); } function completed() { $HistoryEditDialog.modal('hide'); Refresher.update(); if (notification) { PopupNotification.show(notification); notification = null; } } function saveChanges(e) { e.preventDefault(); disableAllButtons(); notification = null; saveCompleted = completed; saveName(); } function saveName() { var name = $('#HistoryEdit_NZBName').val(); name !== curHist.Name && !curHist.postprocess ? RPC.call('editqueue', ['HistorySetName', name, [curHist.ID]], function() { notification = '#Notif_History_Saved'; saveCategory(); }) :saveCategory(); } function saveCategory() { var category = $('#HistoryEdit_Category').val(); category !== curHist.Category && curHist.Kind !== 'DUP' ? RPC.call('editqueue', ['HistorySetCategory', category, [curHist.ID]], function() { notification = '#Notif_History_Saved'; saveDupeKey(); }) : saveDupeKey(); } function itemActions(e) { e.preventDefault(); e.stopPropagation(); var elem = $('#HistoryEdit_Actions').parent(); HistoryActionsMenu.showPopupMenu(curHist, 'top', { left: elem.offset().left, top: elem.offset().top - 1, width: elem.width(), height: elem.height() + 2 }, function(_notification, actionCallback) { disableAllButtons(); notification = _notification; saveCompleted = actionCallback; saveName(); return true; // async }, completed); } /*** TAB: POST-PROCESSING PARAMETERS **************************************************/ function saveParam() { if (curHist.Kind !== 'NZB') { saveCompleted(); return; } var paramList = ParamTab.prepareParamRequest(postParams); saveNextParam(paramList); } function saveNextParam(paramList) { if (paramList.length > 0) { RPC.call('editqueue', ['HistorySetParameter', paramList[0], [curHist.ID]], function() { notification = '#Notif_History_Saved'; paramList.shift(); saveNextParam(paramList); }) } else { saveCompleted(); } } /*** TAB: DUPLICATE SETTINGS **************************************************/ function saveDupeKey() { var value = $('#HistoryEdit_DupeKey').val(); value !== curHist.DupeKey ? RPC.call('editqueue', ['HistorySetDupeKey', value, [curHist.ID]], function() { notification = '#Notif_History_Saved'; saveDupeScore(); }) :saveDupeScore(); } function saveDupeScore() { var value = $('#HistoryEdit_DupeScore').val(); value != curHist.DupeScore ? RPC.call('editqueue', ['HistorySetDupeScore', value, [curHist.ID]], function() { notification = '#Notif_History_Saved'; saveDupeMode(); }) :saveDupeMode(); } function saveDupeMode() { var value = $('#HistoryEdit_DupeMode').val(); value !== curHist.DupeMode ? RPC.call('editqueue', ['HistorySetDupeMode', value, [curHist.ID]], function() { notification = '#Notif_History_Saved'; saveDupeBackup(); }) :saveDupeBackup(); } function saveDupeBackup() { var canChange = curHist.DeleteStatus === 'DUPE' || curHist.DeleteStatus === 'MANUAL'; var oldValue = curHist.DeleteStatus === 'DUPE'; var value = $('#HistoryEdit_DupeBackup').is(':checked'); canChange && value !== oldValue ? RPC.call('editqueue', ['HistorySetDupeBackup', value ? "YES" : "NO", [curHist.ID]], function() { notification = '#Notif_History_Saved'; saveParam(); }) :saveParam(); } }(jQuery));