Files
webgui/emhttp/plugins/dynamix/BrowseButton.page
2025-06-03 14:16:28 -07:00

363 lines
13 KiB
Plaintext

Menu="Buttons:3a"
Title="File Manager"
Icon="icon-u-duplicate"
Code="e963"
---
<?PHP
/* Copyright 2005-2025, Lime Technology
* Copyright 2012-2025, Bergware International.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
?>
<?
$dfm = [
'browser' => $myPage['name'] == 'Browse',
'running' => file_exists('/var/tmp/file.manager.active'),
'jobs' => file_exists('/var/tmp/file.manager.jobs'),
'zfs' => is_executable('/usr/sbin/zfs')
];
if ($dfm['running'] || $dfm['browser']) eval('?>'.parse_file("$docroot/webGui/include/Templates.php"));
?>
<script>
function BrowseButton() {
location.replace('/<?=$task?>/Browse?dir=/mnt');
}
// Prototypes
String.prototype.dfm_patch = function(){return this.replace('rw','x+rw').replace('r-','wx+r').replace('--','rwx');}
String.prototype.dfm_proxy = function(){return this.replace('name','row');}
String.prototype.dfm_fetch = function(tag){return this.replace('check',tag);}
String.prototype.dfm_bring = function(tag){return this.replace('row',tag);}
String.prototype.dfm_strip = function(){return this.replace(/\/$/,'');}
String.prototype.dfm_quote = function(){return this.replace(/&#34;/g,'"');}
String.prototype.dfm_alter = function(...a){var t=this;for(var i=0;i<a.length;i+=2){t=t.replace(a[i],a[i+1]);} return t;}
String.prototype.dfm_build = function(){return this.replace(/\n(<!--!|!-->)\n/g,'');}
String.prototype.dfm_wedge = function(len){len=len||70;return this.length<=len ? this : this.slice(0,Math.round(len/2)-2)+'...'+this.slice(-1-Math.round(len/2));}
// General variables
const dfm = {
window: null,
dialog: false,
running: false,
draggable: false,
previous: '',
height: 0,
tsize: {0: 0, 1: 6, 2: 3, 3: 3, 4: 3, 11: 2, 12: 2, 14: 0, 15: 3},
};
var dfm_read = {};
function dfm_footer(action, text) {
switch (action) {
case 'show':
$('#user-notice').show();
break;
case 'hide':
$('#user-notice').hide();
break;
case 'write':
let icon = '<a class="hand" onclick="dfm_openDialog(true)" title="_(File Manager)_"><i class="icon-u-duplicate dfm"></i></a>';
$('#user-notice').html(icon + text);
break;
case 'clear':
$('#user-notice').html('');
break;
}
}
function dfm_done() {
dfm_footer('write', "<i class='fa fa-circle-thin dfm'></i>_(Searching)_... _(Done)_");
}
function dfm_minimize() {
dfm.window.dialog('close');
dfm_footer('show');
}
function dfm_close_button() {
$('.ui-dfm .ui-dialog-titlebar-close').html('<i class="fa fa-window-minimize"></i>').prop({'title':"_(Minimize)_"}).prop('onclick',null).off('click').click(function(){dfm_minimize();}).show();
}
function dfm_htmlspecialchars(text) {
var map = {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#039;'};
return text.replace(/[&<>"']/g, function(m){return map[m];});
}
function dfm_escapeHTML(name) {
const data = document.createElement('div');
const text = document.createTextNode(name);
data.appendChild(text);
return data.innerHTML;
}
function dfm_createSource(source) {
var select = dfm.window.find('#dfm_source');
if (Array.isArray(source)) {
for (var i=0,object; object=source[i]; i++) {
if (i < 10) {
select.html(select.html()+'<option'+(i==0?' selected':'')+'>'+object+'</option>');
} else {
select.html(select.html()+'<option>&lt;_(more)_&gt; ...</option>');
break;
}
}
} else {
select.html('<option selected>'+source+'</option>');
}
}
function dfm_showProgress(data) {
if (!data) return 0;
let file = null;
let text = data.split('\n');
let line = text[0].split('... ');
let strict = /^mnt|^boot/;
let footer = false;
if (text[0] == '#cat#') {
let loc = [], cat = [];
for (let i=1,row; row=text[i]; i++) {
if (!row) continue;
row = row.split('\0');
loc.push(row[0]);
cat.push(row[1].dfm_wedge(80));
}
if (cat.length > 0) {
dfm.window.find('.dfm_loc').html(loc.join('<br>'));
dfm.window.find('.dfm_text').html(cat.join('<br>'));
dfm.window.find('#dfm_files').html(loc.length+" "+"_(files)_");
}
return cat.length;
} else if (text.length == 1) {
text = text[0].dfm_wedge(80);
footer = text.indexOf("_(Searching)_") != -1;
} else {
if (strict.test(text[1])) {
file = text[1];
text = dfm.previous;
} else {
file = line[1];
text = text[1].split(/\s+/);
text = "<i class='fa fa-circle-o-notch fa-spin dfm'></i>_(Completed)_: "+text[1]+",&nbsp;&nbsp;_(Speed)_: "+text[2]+",&nbsp;&nbsp;_(ETA)_: "+text[3];
dfm.previous = text;
footer = true;
}
}
if (file == null || strict.test(file)) dfm.window.find('.dfm_text').html((file?line[0]+'... /'+dfm_escapeHTML(file.dfm_wedge())+'<br>':'')+text);
if (footer) dfm_footer('write',text);
return 0;
}
function dfm_fileManager(action) {
switch (action) {
case 'start':
$('.ui-dfm .ui-dialog-buttonset button:lt(2)').prop('disabled',true);
<?if ($dfm['browser']):?>
$('.dfm_control').prop('disabled',true);
$('.dfm_control.jobs').prop('disabled',$.cookie('dfm_control.jobs')?false:true);
<?endif;?>
if (!dfm.running) nchan_filemanager.start();
dfm.running = true;
break;
case 'stop':
if (dfm.running) nchan_filemanager.stop();
<?if ($dfm['browser']):?>
dfm.window.find('.dfm_text').removeClass('orange-text').html('');
$('.dfm_control.basic').prop('disabled',false);
$('.dfm_control.common').prop('disabled',$.cookie('dfm_control.common')?true:false);
<?endif;?>
dfm_footer('clear');
dfm.running = false;
break;
}
}
function dfm_makeDialog(open) {
if (open && dfm_read.action == 15) {
dfm.window.dialog('open');
dfm_footer('hide');
return;
}
dfm.window = $('#dfm_dialogWindow');
if (dfm.window.dialog('instance') !== undefined) dfm.dialog = dfm.window.dialog('isOpen');
var dfm_source = dfm_read.source.split('\r').slice(0,9);
switch (dfm_read.action) {
case 0: // create folder/object
dfm.window.html($('#dfm_templateCreateFolder').html());
dfm.height = 330;
break;
case 1: // delete folder/object
dfm.window.html($('#dfm_templateDeleteFolder').html());
dfm.height = 330;
break;
case 2: // rename folder/object
dfm.window.html($('#dfm_templateRenameFolder').html());
dfm.window.find('#dfm_target').val(dfm_read.target.strip().split('/').pop());
dfm.height = 330;
break;
case 3: // copy folder/object
dfm.window.html($('#dfm_templateCopyFolder').html());
dfm.window.find('#dfm_target').val(dfm_read.target).prop('disabled',true);
dfm.window.find('#dfm_sparse').prop('checked',dfm_read.sparse ? true : false);
dfm.window.find('#dfm_exist').prop('checked',dfm_read.exist ? false : true);
dfm.height = 630;
break;
case 4: // move folder/object (rsync)
case 5: // move folder/object (mv)
dfm.window.html($('#dfm_templateMoveFolder').html());
dfm.window.find('#dfm_target').val(dfm_read.target).prop('disabled',true);
dfm.window.find('#dfm_sparse').prop('checked',dfm_read.sparse ? true : false);
dfm.window.find('#dfm_exist').prop('checked',dfm_read.exist ? false : true);
dfm.height = 630;
break;
case 6: // delete file
dfm.window.html($('#dfm_templateDeleteFile').html());
dfm.height = 330;
break;
case 8: // copy file
dfm.window.html($('#dfm_templateCopyFile').html());
dfm.window.find('#dfm_target').val(dfm_read.target).prop('disabled',true);
dfm.window.find('#dfm_sparse').prop('checked',dfm_read.sparse ? true : false);
dfm.window.find('#dfm_exist').prop('checked',dfm_read.exist ? false : true);
dfm.height = 630;
break;
case 9: // move file (rsync)
case 10: // move file (mv)
dfm.window.html($('#dfm_templateMoveFile').html());
dfm.window.find('#dfm_target').val(dfm_read.target).prop('disabled',true);
dfm.window.find('#dfm_sparse').prop('checked',dfm_read.sparse ? true :false);
dfm.window.find('#dfm_exist').prop('checked',dfm_read.exist ? false : true);
dfm.height = 630;
break;
case 11: // change owner
dfm.window.html($('#dfm_templateChangeOwner').html());
dfm.window.find('#dfm_target').prop('disabled',true);
dfm.height = 330;
break;
case 12: // change permission
dfm.window.html($('#dfm_templateChangePermission').html());
dfm.window.find('#dfm_owner').prop('disabled',true);
dfm.window.find('#dfm_group').prop('disabled',true);
dfm.window.find('#dfm_other').prop('disabled',true);
dfm.height = 330;
break;
case 15: // search
dfm.window.html($('#dfm_templateSearch').html());
dfm.window.find('#dfm_target').val(dfm_read.target).prop('disabled',true);
dfm.window.find('.dfm_loc').html('&nbsp;').css({'line-height':'normal'});
dfm.window.find('.dfm_text').html('').css({'line-height':'normal'});
dfm.height = 630;
break;
}
dfm.window.find('#dfm_source').attr('size',Math.min(dfm.tsize[dfm_read.action],dfm_source.length));
dfm_createSource(dfm_source);
dfm.window.find('#dfm_sparse').prop('disabled',true);
dfm.window.find('#dfm_exist').prop('disabled',true);
dfm.window.find('.dfm_sparse').css({'opacity':'0.5'});
dfm.window.find('.dfm_exist').css({'opacity':'0.5'});
dfm.window.dialog({
classes: {'ui-dialog': 'ui-dfm'},
autoOpen: open || dfm.dialog,
title: dfm_read.title,
height: dfm.height,
width: 'auto',
resizable: false,
draggable: false,
modal: true,
buttons: {
"_(Start)_": function(){
if (dfm_read.action == 15) {
var dfm_target = dfm.window.find('#dfm_target').val();
dfm.window.find('.dfm_loc').html('&nbsp;');
dfm.window.find('.dfm_text').html("_(Running)_...");
dfm_footer('hide');
dfm_fileManager('start');
$.post('/webGui/include/Control.php',{mode:'file',action:15,title:encodeURIComponent(dfm_read.title),source:encodeURIComponent(dfm_read.source),target:encodeURIComponent(dfm_target),hdlink:'',sparse:'',exist:'',zfs:''});
} else {
return;
}
},
"_(Queue)_": function(){
return;
},
"_(Cancel)_": function(){
dfm_fileManager('stop');
dfm.window.dialog('destroy');
$.post('/webGui/include/Control.php',{mode:'file',action:99},function(){<?if ($dfm['browser']):?>setTimeout(loadList,500);<?endif;?>});
}
}
});
dfm_close_button();
$('.ui-dfm .ui-dialog-buttonset button:lt(2)').prop('disabled',true);
setTimeout(function(){$('.ui-dfm .ui-dialog-buttonset button:eq(2)').focus();});
if (open||dfm.dialog) dfm_footer('hide'); else dfm_footer('show');
}
function dfm_openDialog(open) {
$.post('/webGui/include/Control.php',{mode:'read'},function(data){
if (data) {
dfm_read = JSON.parse(data);
dfm_read.action = parseInt(dfm_read.action);
}
dfm_makeDialog(open);
});
}
var nchan_filemanager = new NchanSubscriber('/sub/filemanager',{subscriber:'websocket'});
nchan_filemanager.on('message', function(msg) {
let data = $.parseJSON(msg);
if (data.error) {
dfm_fileManager('stop');
dfm.window.find('.dfm_text').addClass('orange-text').html(data.error);
dfm.window.find('#dfm_target').prop('disabled',false);
dfm.window.find('#dfm_sparse').prop('disabled',false);
dfm.window.find('#dfm_exist').prop('disabled',false);
dfm.window.find('#dfm_owner').prop('disabled',false);
dfm.window.find('#dfm_group').prop('disabled',false);
dfm.window.find('#dfm_other').prop('disabled',false);
$('.ui-dfm .ui-dialog-buttonset button:lt(2)').prop('disabled',false);
} else {
let cat = dfm_showProgress(data.status);
if (data.done == 1) {
setTimeout(function(){$.post('/webGui/include/Control.php',{mode:'start'},function(queue){
switch (parseInt(queue)) {
case 0:
dfm_fileManager('stop');
dfm.window.dialog('destroy');
<?if ($dfm['browser']):?>
setTimeout(loadList);
<?endif;?>
break;
case 1:
<?if ($dfm['browser']):?>
$('.dfm_control.jobs').prop('disabled',true);
<?endif;?>
$.removeCookie('dfm_control.jobs');
case 2:
dfm_openDialog();
break;
}
})});
} else if (data.done == 2) {
nchan_filemanager.stop();
dfm.running = false;
dfm.window.find('#dfm_target').prop('disabled',false).focus();
$('.ui-dfm .ui-dialog-buttonset button:eq(0)').prop('disabled',false);
if (cat == 0) dfm.window.find('.dfm_text').html("_(No results found)_");
if ($('#user-notice:visible')) dfm_done();
}
}
});
<?if ($dfm['running']):?>
$(function(){
dfm_openDialog();
dfm_fileManager('start');
});
<?endif;?>
</script>