1 // Bweb - A Bacula web interface
2 // Bacula® - The Network Backup Solution
4 // Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
6 // The main author of Bweb is Eric Bollengier.
7 // The main author of Bacula is Kern Sibbald, with contributions from
8 // many others, a complete list can be found in the file AUTHORS.
10 // This program is Free Software; you can redistribute it and/or
11 // modify it under the terms of version two of the GNU General Public
12 // License as published by the Free Software Foundation plus additions
13 // that are listed in the file LICENSE.
15 // This program is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // General Public License for more details.
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 // Bacula® is a registered trademark of Kern Sibbald.
26 // The licensor of Bacula is the Free Software Foundation Europe
27 // (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zurich,
28 // Switzerland, email:ftf@fsfeurope.org.
30 // render if vol is online/offline
31 function rd_vol_is_online(val)
33 return '<img src="inflag' + val + '.png">';
36 // TODO: fichier ou rep
37 function rd_file_or_dir(val)
40 return '<img src="file_f.png">';
42 return '<img src="file_d.png">';
48 Ext.brestore.path_stack.push(Ext.brestore.path);
49 Ext.brestore.pathid_stack.push(Ext.brestore.pathid);
50 Ext.ComponentMgr.get('prevbp').enable();
54 var pathid = Ext.brestore.pathid_stack.pop();
55 var path = Ext.brestore.path_stack.pop();
57 Ext.ComponentMgr.get('prevbp').disable();
60 Ext.ComponentMgr.get('wherefield').setValue(path);
62 Ext.brestore.pathid = pathid;
63 Ext.brestore.path = path;
67 function dirname(path) {
68 var a = path.match( /(^.*\/).+\// );
75 Ext.namespace('Ext.brestore');
76 Ext.brestore.jobid=0; // selected jobid
77 Ext.brestore.jobdate=''; // selected date
78 Ext.brestore.client=''; // selected client
79 Ext.brestore.rclient=''; // selected client for resto
80 Ext.brestore.storage=''; // selected storage for resto
81 Ext.brestore.path=''; // current path (without user location)
82 Ext.brestore.pathid=0; // current pathid
83 Ext.brestore.root_path=''; // user location
84 Ext.brestore.media_store; // media store
85 Ext.brestore.option_vosb = false;
86 Ext.brestore.option_vafv = false;
87 Ext.brestore.option_vcopies = false;
88 Ext.brestore.dlglaunch;
89 Ext.brestore.fpattern;
90 Ext.brestore.use_filerelocation=false;
91 Ext.brestore.limit = 500;
92 Ext.brestore.offset = 0;
93 Ext.brestore.force_reload = 0;
94 Ext.brestore.path_stack = Array();
95 Ext.brestore.pathid_stack = Array();
96 Ext.brestore.dir = get_current_director();
98 function get_node_path(node)
101 for (var p = node; p; p = p.parentNode) {
103 temp = p.text + temp;
106 return Ext.brestore.root_path + temp;
109 function init_params(baseParams)
111 baseParams['client']= Ext.brestore.client;
113 if (Ext.brestore.option_vosb) {
114 baseParams['jobid'] = Ext.brestore.jobid;
116 baseParams['date'] = Ext.brestore.jobdate;
118 baseParams['offset'] = Ext.brestore.offset;
119 baseParams['limit'] = Ext.brestore.limit;
120 if (Ext.brestore.fpattern) {
121 if (RegExp(Ext.brestore.fpattern)) {
122 baseParams['pattern'] = Ext.brestore.fpattern;
125 if (Ext.brestore.dir) {
126 baseParams['dir'] = Ext.brestore.dir;
131 function captureEvents(observable) {
132 Ext.util.Observable.capture(
134 function(eventName) {
135 console.info(eventName);
141 ////////////////////////////////////////////////////////////////
143 Ext.BLANK_IMAGE_URL = 'ext/resources/images/default/s.gif';
144 Ext.onReady(function(){
145 if (!Ext.version || Ext.version < 2.2) {
146 alert("You must upgrade your extjs version to 2.2");
150 Ext.QuickTips.init();
152 // Init tree for directory selection
153 var tree_loader = new Ext.tree.TreeLoader({
155 dataUrl:'/cgi-bin/bweb/bresto.pl'
158 var tree = new Ext.tree.TreePanel({
162 enableDragDrop: true,
163 containerScroll: true,
164 title: 'Directories',
169 var root = new Ext.tree.AsyncTreeNode({
170 text: 'Select a client then a job',
174 tree.setRootNode(root);
175 Ext.brestore.tree = root; // shortcut
177 var click_cb = function(node, event) {
180 Ext.brestore.path = get_node_path(node);
181 Ext.brestore.pathid = node.id;
182 Ext.brestore.offset=0;
183 Ext.brestore.fpattern = Ext.get('txt-file-pattern').getValue();
184 where_field.setValue(Ext.brestore.path);
186 file_store.load({params:init_params({action: 'list_files_dirs',
187 path:Ext.brestore.path,
193 tree.on('click', click_cb);
195 tree.on('beforeload', function(e,b) {
197 // file_store.removeAll();
200 tree.on('load', function(n,e) {
207 ////////////////////////////////////////////////////////////////
209 var file_store = new Ext.data.Store({
210 proxy: new Ext.data.HttpProxy({
211 url: '/cgi-bin/bweb/bresto.pl',
216 reader: new Ext.data.ArrayReader({},
217 Ext.data.Record.create([
219 {name: 'filenameid'},
223 {name: 'size', type: 'int' },
224 {name: 'mtime', type: 'date', dateFormat: 'Y-m-d h:i:s'},
230 Ext.brestore.file_store=file_store;
231 var cm = new Ext.grid.ColumnModel([{
234 dataIndex: 'filenameid',
236 css: 'white-space:normal;',
237 renderer: rd_file_or_dir
239 id: 'cm-id', // id assigned so we can apply custom css
240 // (e.g. .x-grid-col-topic b { color:#333 })
244 css: 'white-space:normal;'
248 renderer: human_size,
253 renderer: Ext.util.Format.dateRenderer('Y-m-d h:i'),
260 header: "FilenameId",
261 dataIndex: 'filenameid',
277 // by default columns are sortable
278 cm.defaultSortable = true;
281 function update_limits() {
282 Ext.get('txt-file-offset').dom.value = Ext.brestore.offset;
283 Ext.get('txt-file-limit').dom.value = Ext.brestore.offset + Ext.brestore.limit;
286 // get limits from user input
287 function update_user_limits() {
288 var off = parseInt(Ext.get('txt-file-offset').getValue());
289 var lim = parseInt(Ext.get('txt-file-limit').getValue());
290 if (off >= 0 && lim >= 0 && off < lim) {
291 Ext.brestore.offset = off;
292 Ext.brestore.limit = lim - off;
296 Ext.brestore.fpattern = Ext.get('txt-file-pattern').getValue();
299 var file_paging_next = new Ext.Toolbar.Button({
301 icon: 'ext/resources/images/default/grid/page-next.gif',
304 handler: function(a,b,c) {
305 update_user_limits();
306 if (file_store.getCount() >= Ext.brestore.limit) {
307 Ext.brestore.offset += Ext.brestore.limit;
308 file_store.removeAll();
309 file_versions_store.removeAll();
310 file_store.load({params:init_params({action: 'list_files_dirs',
311 path:Ext.brestore.path,
312 node:Ext.brestore.pathid})
317 var file_paging_prev = new Ext.Toolbar.Button({
319 icon: 'ext/resources/images/default/grid/page-prev.gif',
322 handler: function() {
323 update_user_limits();
324 if (Ext.brestore.offset > 0) {
325 Ext.brestore.offset -= Ext.brestore.limit;
326 if (Ext.brestore.offset < 0) {
327 Ext.brestore.offset=0;
329 file_store.removeAll();
330 file_versions_store.removeAll();
331 file_store.load({params:init_params({action: 'list_files_dirs',
332 path:Ext.brestore.path,
333 node:Ext.brestore.pathid})
338 var file_paging_pattern = new Ext.form.TextField({
339 enableKeyEvents: true,
340 id: 'txt-file-pattern',
343 file_paging_pattern.on('keyup', function(a, e) {
344 if (e.getKey() == e. ENTER) {
346 var pattern = file_paging_pattern.getValue();
348 re = new RegExp(pattern, "i");
351 file_store.filter('name', re);
353 file_store.clearFilter(false);
357 var file_paging = new Ext.Toolbar({
358 items: [file_paging_prev, {
359 id: 'txt-file-offset',
360 xtype: 'numberfield',
362 value: Ext.brestore.offset
367 id: 'txt-file-limit',
368 xtype: 'numberfield',
370 value: Ext.brestore.limit
371 }, file_paging_next, '->', file_paging_pattern, {
373 icon: 'ext/resources/images/default/grid/refresh.gif',
376 handler: function(a,b,c) {
377 update_user_limits();
378 file_store.removeAll();
379 file_versions_store.removeAll();
380 file_store.load({params:init_params({action: 'list_files_dirs',
381 path:Ext.brestore.path,
382 node:Ext.brestore.pathid})
387 var file_grid = new Ext.grid.GridPanel({
392 enableDragDrop: true,
393 selModel: new Ext.grid.RowSelectionModel(),
395 autoSizeColumns: true,
398 title: 'Directory content',
401 Ext.brestore.file_grid=file_grid;
402 // when we reload the view,
403 // we clear the file version box
404 file_store.on('beforeload', function(e) {
405 file_store.removeAll();
406 file_versions_store.removeAll();
410 // If we have more than limit elements, we can
411 // display the next button
412 file_store.on('load', function(e,o) {
414 if (e.getCount() >= Ext.brestore.limit) {
415 file_paging_next.enable();
417 file_paging_next.disable();
420 if (Ext.brestore.offset) {
421 file_paging_prev.enable();
423 file_paging_prev.disable();
429 * file_store.on('loadexception', function(obj, options, response, e){
430 * console.info('store loadexception, arguments:', arguments);
431 * console.info('error = ', e);
434 * file_store.on('load', function(store, records, options){
435 * //store is loaded, now you can work with it's records, etc.
436 * console.info('store load, arguments:', arguments);
437 * console.info('Store count = ', store.getCount());
440 file_grid.on('celldblclick', function(e) {
441 var r = e.selModel.getSelected();
443 if (r.json[1] == 0) { // select a directory
446 if (r.json[4] == '..') {
447 Ext.brestore.path = dirname(Ext.brestore.path);
448 } else if (r.json[4] == '/') {
449 Ext.brestore.path = '/';
450 } else if (r.json[4] != '.') {
451 Ext.brestore.path = Ext.brestore.path + r.json[4];
453 Ext.brestore.pathid = r.json[2];
454 Ext.brestore.filename = '';
455 Ext.brestore.offset=0;
456 Ext.brestore.fpattern = Ext.get('txt-file-pattern').getValue();
457 where_field.setValue(Ext.brestore.path);
459 file_store.load({params:init_params({action: 'list_files_dirs',
460 path:Ext.brestore.path,
461 node:Ext.brestore.pathid})
466 // TODO: selection only when using dblclick
467 file_grid.selModel.on('rowselect', function(e,i,r) {
468 if (r.json[1] == 0) { // select a directory
472 Ext.brestore.filename = r.json[4];
473 file_versions_store.load({
474 params:init_params({action: 'list_versions',
475 vafv: Ext.brestore.option_vafv,
476 vcopies: Ext.brestore.option_vcopies,
478 filenameid: r.json[1]
484 ////////////////////////////////////////////////////////////////
486 var file_selection_store = new Ext.data.Store({
487 proxy: new Ext.data.MemoryProxy(),
489 reader: new Ext.data.ArrayReader({},
490 Ext.data.Record.create([
493 {name: 'filenameid'},
496 {name: 'size', type: 'int' },
502 var file_selection_cm = new Ext.grid.ColumnModel([
504 id: 'file-selection-id',
515 renderer: human_size,
520 // renderer: Ext.util.Format.dateRenderer('Y-m-d h:i'),
527 header: 'Filenameid',
528 dataIndex: 'filenameid',
542 var file_selection_grid = new Ext.grid.GridPanel({
543 colModel: file_selection_cm,
544 store: file_selection_store,
546 enableDragDrop: false,
547 selModel: new Ext.grid.RowSelectionModel(),
556 var file_selection_record = Ext.data.Record.create(
559 {name: 'filenameid'},
565 // captureEvents(file_selection_grid);
566 // captureEvents(file_selection_store);
568 func1 = function(e,b,c) {
569 if (e.browserEvent.keyCode == 46) {
570 var m = file_selection_grid.getSelections();
572 for(var i = 0, len = m.length; i < len; i++){
573 file_selection_store.remove(m[i]);
578 file_selection_grid.on('keypress', func1);
580 ////////////////////////////////////////////////////////////////
582 var file_versions_store = new Ext.data.Store({
583 proxy: new Ext.data.HttpProxy({
584 url: '/cgi-bin/bweb/bresto.pl',
586 params:{offset:0, limit:50 }
589 reader: new Ext.data.ArrayReader({},
590 Ext.data.Record.create([
592 {name: 'filenameid'},
596 {name: 'inchanger' },
598 {name: 'size', type: 'int' },
599 {name: 'mtime', type: 'date', dateFormat: 'Y-m-d h:i:s'},
604 var file_versions_cm = new Ext.grid.ColumnModel([{
605 id: 'file-version-id',
610 dataIndex: 'inchanger',
612 renderer: rd_vol_is_online
624 renderer: human_size,
629 renderer: Ext.util.Format.dateRenderer('Y-m-d h:i'),
640 header: "filenameid",
641 dataIndex: 'filenameid',
653 // by default columns are sortable
654 file_versions_cm.defaultSortable = true;
657 var file_versions_grid = new Ext.grid.GridPanel({
658 id: 'div-file-versions',
659 store: file_versions_store,
660 colModel: file_versions_cm,
662 enableDragDrop: true,
663 selModel: new Ext.grid.RowSelectionModel(),
667 title: 'File version',
671 file_versions_grid.on('rowdblclick', function(e) {
672 file_versions_store.removeAll(); return true;
676 ////////////////////////////////////////////////////////////////
678 var client_store = new Ext.data.Store({
679 proxy: new Ext.data.HttpProxy({
680 url: '/cgi-bin/bweb/bresto.pl',
682 params:{action:'list_client'}
685 reader: new Ext.data.ArrayReader({
686 }, Ext.data.Record.create([
691 var client_combo = new Ext.form.ComboBox({
692 fieldLabel: 'Clients',
697 triggerAction: 'all',
698 emptyText:'Select a client...',
700 forceSelection: true,
704 var replace_store = new Ext.data.SimpleStore({
705 fields: ['value', 'text'],
706 data : [['never', 'Never'],['always', 'Always']]
709 var replace_combo = new Ext.form.ComboBox({
710 fieldLabel: 'Replace',
711 store: replace_store,
715 triggerAction: 'all',
716 emptyText:'Replace mode...',
718 forceSelection: true,
722 client_combo.on('valid', function(e) {
723 Ext.brestore.client = e.getValue();
724 Ext.brestore.jobid=0;
725 Ext.brestore.jobdate = '';
726 Ext.brestore.root_path='';
727 Ext.brestore.offset=0;
728 job_combo.clearValue();
729 file_store.removeAll();
730 file_versions_store.removeAll();
731 root.collapse(false, false);
732 while(root.firstChild){
733 root.removeChild(root.firstChild);
735 job_store.load( {params:{action: 'list_job',dir: Ext.brestore.dir,
736 client:Ext.brestore.client}});
740 //////////////////////////////////////////////////////////////:
742 var job_store = new Ext.data.Store({
743 proxy: new Ext.data.HttpProxy({
744 url: '/cgi-bin/bweb/bresto.pl',
746 params:{offset:0, limit:50 }
749 reader: new Ext.data.ArrayReader({
750 }, Ext.data.Record.create([
757 var job_combo = new Ext.form.ComboBox({
760 displayField: 'jobname',
762 triggerAction: 'all',
763 emptyText: 'Select a job...',
767 forceSelection: true,
771 job_combo.on('select', function(e,c) {
772 Ext.brestore.jobid = c.json[0];
773 Ext.brestore.jobdate = c.json[1];
774 root.setText("Root");
775 tree_loader.baseParams = init_params({init:1, action: 'list_dirs',
779 file_store.load({params:init_params({action: 'list_files_dirs',
780 path:Ext.brestore.path,
781 node:Ext.brestore.pathid})
785 var where_field = new Ext.form.TextField({
786 fieldLabel: 'Location',
793 function sel_option(item, check)
795 if (item.id == 'id_vosb') {
796 Ext.brestore.option_vosb = check;
798 if (item.id == 'id_vafv') {
799 Ext.brestore.option_vafv = check;
801 if (item.id == 'id_vcopies') {
802 Ext.brestore.option_vcopies = check;
806 var menu = new Ext.menu.Menu({
809 new Ext.menu.CheckItem({
811 text: 'View only selected backup',
812 checked: Ext.brestore.option_vosb,
813 checkHandler: sel_option
815 new Ext.menu.CheckItem({
817 text: 'View all file versions',
818 checked: Ext.brestore.option_vafv,
819 checkHandler: sel_option
821 new Ext.menu.CheckItem({
823 text: 'View copies version',
824 checked: Ext.brestore.option_vcopies,
825 checkHandler: sel_option
830 var tb = new Ext.Toolbar({
840 handler: function() {
844 Ext.brestore.offset=0;
846 file_store.load({params:init_params({action: 'list_files_dirs',
847 node:Ext.brestore.pathid})
854 text: 'Change location',
855 cls:'x-btn-text-icon',
856 handler: function() {
857 var where = where_field.getValue();
859 Ext.MessageBox.show({
860 title: 'Bad parameter',
861 msg: 'Location is empty!',
862 buttons: Ext.MessageBox.OK,
863 icon: Ext.MessageBox.ERROR
867 Ext.brestore.root_path=where;
869 tree_loader.baseParams = init_params({
870 action:'list_dirs', path: where, skipdot: 1
878 iconCls: 'bmenu', // <-- icon
879 menu: menu // assign menu by instance
882 { // TODO: put this button on south panel
883 icon: 'mR.png', // icons can also be specified inline
884 cls: 'x-btn-text-icon',
885 tooltip: 'Run restore',
887 handler: function() {
888 if (!file_selection_store.data.items.length) {
889 Ext.MessageBox.show({
890 title: 'Empty selection',
891 msg: 'Your object selection list is empty!',
892 buttons: Ext.MessageBox.OK,
893 icon: Ext.MessageBox.ERROR
902 ////////////////////////////////////////////////////////////////
904 // Define Main interface
905 var MainView = new Ext.Viewport({
907 title: 'Bacula Web Restore',
910 renderTo: Ext.getBody(),
922 title: 'Directories',
928 title: 'Directory content',
934 title: 'File version',
938 items: file_versions_grid
941 title: 'Restore selection',
945 items: file_selection_grid
948 client_store.load({params:{action: 'list_client', dir: Ext.brestore.dir}});
950 // data.selections[0].json[]
952 // http://extjs.com/forum/showthread.php?t=12582&highlight=drag+drop
954 var horror_show1 = file_selection_grid.getView().el.dom;
955 var ddrow = new Ext.dd.DropTarget(horror_show1, {
958 notifyDrop : function(dd, e, data){
960 if (data.selections) {
961 if (data.grid.id == 'div-files') {
962 for(var i=0;i<data.selections.length;i++) {
963 var name = data.selections[i].json[4];
964 var fnid = data.selections[i].json[1];
965 if (fnid == 0 && name != '..') {
968 r = new file_selection_record({
969 jobid: data.selections[0].json[3],
970 fileid: data.selections[i].json[0],
971 filenameid:data.selections[i].json[1],
972 pathid: data.selections[i].json[2],
973 name: Ext.brestore.path + ((name=='..')?'':name),
974 size: data.selections[i].json[5],
975 mtime: data.selections[i].json[6],
976 LinkFI: data.selections[i].json[7]
978 file_selection_store.add(r);
982 if (data.grid.id == 'div-file-versions') {
983 r = new file_selection_record({
984 jobid: data.selections[0].json[3],
985 fileid: data.selections[0].json[0],
986 filenameid:data.selections[0].json[1],
987 pathid: data.selections[0].json[2],
988 name: Ext.brestore.path + Ext.brestore.filename,
989 size: data.selections[0].json[7],
990 mtime: data.selections[0].json[8],
991 LinkFI: data.selections[0].json[9],
993 file_selection_store.add(r)
998 var path= get_node_path(data.node);
999 r = new file_selection_record({
1000 jobid: data.node.attributes.jobid,
1003 pathid: data.node.id,
1009 file_selection_store.add(r)
1015 function force_reload_media_store() {
1016 Ext.brestore.force_reload = 1;
1017 reload_media_store();
1018 Ext.brestore.force_reload = 0;
1021 function reload_media_store() {
1022 Ext.brestore.media_store.removeAll();
1023 var items = file_selection_store.data.items;
1024 var tab_fileid=new Array();
1025 var tab_dirid=new Array();
1026 var tab_jobid=new Array();
1027 var enable_compute=false;
1028 for(var i=0;i<items.length;i++) {
1029 if (items[i].data['fileid']) {
1030 tab_fileid.push(items[i].data['fileid']);
1032 tab_dirid.push(items[i].data['pathid']);
1033 enable_compute=true;
1035 tab_jobid.push(items[i].data['jobid']);
1037 var res = tab_fileid.join(",");
1038 var res2 = tab_jobid.join(",");
1039 var res3 = tab_dirid.join(",");
1041 Ext.brestore.media_store.baseParams = init_params({
1042 action: 'get_media',
1046 force: Ext.brestore.force_reload
1048 Ext.brestore.media_store.load();
1049 if (enable_compute) {
1050 Ext.get('reload_media').show();
1052 Ext.get('reload_media').hide();
1056 function display_run_job() {
1057 if (Ext.brestore.dlglaunch) {
1058 reload_media_store();
1059 Ext.brestore.dlglaunch.show();
1062 var rclient_combo = new Ext.form.ComboBox({
1063 value: Ext.brestore.client,
1064 fieldLabel: 'Client',
1065 hiddenName:'client',
1066 store: client_store,
1067 displayField:'name',
1070 triggerAction: 'all',
1071 emptyText:'Select a client...',
1072 forceSelection: true,
1076 var storage_store = new Ext.data.Store({
1077 proxy: new Ext.data.HttpProxy({
1078 url: '/cgi-bin/bweb/bresto.pl',
1080 params:{action:'list_storage'}
1083 reader: new Ext.data.ArrayReader({
1084 }, Ext.data.Record.create([
1089 var storage_combo = new Ext.form.ComboBox({
1090 value: Ext.brestore.storage,
1091 fieldLabel: 'Storage',
1092 hiddenName:'storage',
1093 store: storage_store,
1094 displayField:'name',
1097 triggerAction: 'all',
1098 emptyText:'Select a storage...',
1099 forceSelection: false,
1104 var comment_text = new Ext.form.TextField({
1105 fieldLabel: 'Comment',
1110 var where_text = new Ext.form.TextField({
1111 fieldLabel: 'Where',
1113 value: '/tmp/bacula-restore'
1115 var stripprefix_text = new Ext.form.TextField({
1116 fieldLabel: 'Strip prefix',
1117 name: 'strip_prefix',
1121 var addsuffix_text = new Ext.form.TextField({
1122 fieldLabel: 'Add suffix',
1127 var addprefix_text = new Ext.form.TextField({
1128 fieldLabel: 'Add prefix',
1133 var rwhere_text = new Ext.form.TextField({
1134 fieldLabel: 'Where regexp',
1135 name: 'regexp_where',
1139 var useregexp_bp = new Ext.form.Checkbox({
1140 fieldLabel: 'Use regexp',
1144 handler: function(bp,state) {
1146 addsuffix_text.disable();
1147 addprefix_text.disable();
1148 stripprefix_text.disable();
1149 rwhere_text.enable();
1151 addsuffix_text.enable();
1152 addprefix_text.enable();
1153 stripprefix_text.enable();
1154 rwhere_text.disable();
1159 var usefilerelocation_bp = new Ext.form.Checkbox({
1160 fieldLabel: 'Use file relocation',
1161 name: 'use_relocation',
1165 usefilerelocation_bp.on('check', function(bp,state) {
1167 where_text.disable();
1168 useregexp_bp.enable();
1169 if (useregexp_bp.getValue()) {
1170 addsuffix_text.disable();
1171 addprefix_text.disable();
1172 stripprefix_text.disable();
1173 rwhere_text.enable();
1175 addsuffix_text.enable();
1176 addprefix_text.enable();
1177 stripprefix_text.enable();
1178 rwhere_text.disable();
1181 where_text.enable();
1182 addsuffix_text.disable();
1183 addprefix_text.disable();
1184 stripprefix_text.disable();
1185 useregexp_bp.disable();
1186 rwhere_text.disable();
1188 Ext.brestore.use_filerelocation = state;
1191 useregexp_bp.on('check', function(bp,state) {
1193 addsuffix_text.disable();
1194 addprefix_text.disable();
1195 stripprefix_text.disable();
1196 rwhere_text.enable();
1198 addsuffix_text.enable();
1199 addprefix_text.enable();
1200 stripprefix_text.enable();
1201 rwhere_text.disable();
1205 var media_store = Ext.brestore.media_store = new Ext.data.Store({
1206 proxy: new Ext.data.HttpProxy({
1207 url: '/cgi-bin/bweb/bresto.pl',
1209 params:{offset:0, limit:50}
1212 reader: new Ext.data.ArrayReader({
1213 }, Ext.data.Record.create([
1214 {name: 'volumename'},
1216 {name: 'inchanger' }
1220 var media_cm = new Ext.grid.ColumnModel(
1222 header: "InChanger",
1223 dataIndex: 'inchanger',
1225 renderer: rd_vol_is_online
1229 dataIndex: 'volumename',
1235 var media_grid = new Ext.grid.GridPanel({
1236 id: 'div-media-grid',
1239 enableDragDrop: false,
1246 var form_panel = new Ext.FormPanel({
1247 labelWidth : 75, // label settings here cascade unless overridden
1249 bodyStyle : 'padding:5px 5px 0',
1251 // autoHeight : true,
1257 bodyStyle : 'padding:5px 5px 0',
1258 deferredRender : false,
1261 title : 'Restore details',
1264 title : 'Restore options',
1266 defaults : {width: 210},
1267 bodyStyle : 'padding:5px 5px 0',
1268 items :[ rclient_combo, where_text, replace_combo, comment_text ]
1271 title : 'Media needed',
1273 defaults : {width: 280},
1274 bodyStyle : 'padding:5px 5px 0',
1275 items :[ media_grid,
1276 {xtype: 'button', id: 'reload_media',
1277 text: 'Compute with directories',
1278 tooltip: 'Can take long time...',
1279 handler:force_reload_media_store}]
1286 title : 'File relocation',
1288 defaults : {width: 210},
1289 bodyStyle : 'padding:5px 5px 0',
1290 items :[ usefilerelocation_bp, stripprefix_text,
1291 addprefix_text, addsuffix_text, useregexp_bp,
1295 title : 'Other options',
1297 defaults : {width: 210},
1298 bodyStyle : 'padding:5px 5px 0',
1299 defaultType : 'textfield',
1304 tooltip: 'YYY-MM-DD HH:MM'
1307 fieldLabel: 'Priority',
1317 handler: function() {
1318 if(!form_panel.getForm().isValid()) { alert("invalid") }
1319 else { launch_restore() }
1323 handler: function() { Ext.brestore.dlglaunch.hide(); }
1327 Ext.brestore.dlglaunch = new Ext.Window({
1328 applyTo : 'resto-div',
1329 title : 'Restore selection',
1333 closeAction :'hide',
1338 // Ext.brestore.dlglaunch.addKeyListener(27,
1339 // Ext.brestore.dlglaunch.hide,
1340 // Ext.brestore.dlglaunch);
1341 ////////////////////////////////////////////////////////////////
1343 function launch_restore() {
1344 var items = file_selection_store.data.items;
1345 var tab_fileid=new Array();
1346 var tab_dirid=new Array();
1347 var tab_jobid=new Array();
1348 var tab_findex=new Array();
1349 for(var i=0;i<items.length;i++) {
1350 // For hardlinks, we include fileindex/jobid
1351 if (items[i].data['LinkFI']) {
1352 tab_findex.push(items[i].data['jobid']
1353 + '/' + items[i].data['LinkFI']);
1355 if (items[i].data['fileid']) {
1356 tab_fileid.push(items[i].data['fileid']);
1358 tab_dirid.push(items[i].data['pathid']);
1360 tab_jobid.push(items[i].data['jobid']);
1363 if (Ext.brestore.dir) {
1364 dir = ";dir=" + encodeURIComponent(Ext.brestore.dir);
1367 var res = ';fileid=' + tab_fileid.join(";fileid=");
1368 var res2 = ';dirid=' + tab_dirid.join(";dirid=");
1369 var res3 = ';jobid=' + tab_jobid.join(";jobid=");
1370 var res4 = ';client=' + encodeURIComponent(rclient_combo.getValue());
1371 var res5 = ';findex=' + tab_findex.join(";findex=");
1372 if (comment_text.getValue()) {
1373 res4 = res4 + ';comment=' + encodeURIComponent(comment_text.getValue());
1375 if (storage_combo.getValue()) {
1376 res4 = res4 + ';storage=' + storage_combo.getValue();
1378 if (Ext.brestore.use_filerelocation) {
1379 if (useregexp_bp.getValue()) {
1380 res4 = res4 + ';regexwhere=' + encodeURIComponent(rwhere_text.getValue());
1382 var reg = new Array();
1383 if (stripprefix_text.getValue()) {
1384 reg.push(encodeURIComponent('!' + stripprefix_text.getValue() + '!!i'));
1386 if (addprefix_text.getValue()) {
1387 reg.push(encodeURIComponent('!^!' + addprefix_text.getValue() + '!'));
1389 if (addsuffix_text.getValue()) {
1390 reg.push(encodeURIComponent('!([^/])$!$1' + addsuffix_text.getValue() + '!'));
1392 res4 = res4 + ';regexwhere=' + reg.join(',');
1395 res4 = res4 + ';where=' + encodeURIComponent(where_text.getValue());
1397 window.location='/cgi-bin/bweb/bresto.pl?action=restore' + dir + res + res2 + res3 + res5 + res4;
1398 } // end launch_restore
1401 ////////////////////////////////////////////////////////////////
1402 reload_media_store();
1403 storage_store.load({params:init_params({action: 'list_storage'})});
1404 Ext.brestore.dlglaunch.show();