]> git.proxmox.com Git - pmg-gui.git/commitdiff
add MailTracker
authorDietmar Maurer <dietmar@proxmox.com>
Thu, 21 Sep 2017 07:47:48 +0000 (09:47 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Thu, 21 Sep 2017 07:47:48 +0000 (09:47 +0200)
js/MailTracker.js [new file with mode: 0644]
js/Makefile
js/NavigationTree.js
js/Utils.js

diff --git a/js/MailTracker.js b/js/MailTracker.js
new file mode 100644 (file)
index 0000000..c515199
--- /dev/null
@@ -0,0 +1,342 @@
+Ext.define('pmg-mail-tracker', {
+    extend: 'Ext.data.Model',
+    fields: [
+       'id' , 'from', 'to', 'dstatus', 'rstatus', 'qid', 'msgid', 'client',
+       { type: 'number', name: 'size' },
+       { type: 'date', dateFormat: 'timestamp', name: 'time' }
+    ],
+    proxy: {
+       type: 'proxmox'
+    },
+    idProperty: 'id'
+});
+
+
+Ext.define('PMG.MailTrackerFilter', {
+    extend: 'Ext.container.Container',
+    xtype: 'pmgMailTrackerFilter',
+
+    layout: {
+       type: 'hbox'
+    },
+
+    controller: {
+
+        xclass: 'Ext.app.ViewController',
+
+       onFilterChange: function() {
+           var view = this.getView();
+           view.fireEvent('filterChanged');
+       },
+
+       onSpecialKey: function(field, e) {
+           if (e.getKey() == e.ENTER) {
+               this.onFilterChange();
+           }
+       }
+    },
+
+    getFilterParams: function() {
+       var me = this;
+       var param = {};
+
+       var names = ['from', 'target', 'xfilter', 'starttime', 'endtime', 'ndr', 'greylist'];
+       Ext.Array.each(names, function(name) {
+           var value = me.lookupReference(name).getSubmitValue();
+           if (value) { param[name] = value; }
+       });
+
+       return param;
+    },
+
+    items: [
+       {
+           width: 400,
+           border: false,
+           padding: 10,
+           layout: {
+               type: 'vbox',
+               align: 'stretch'
+           },
+           items: [
+               {
+                   fieldLabel: gettext('Sender'),
+                   xtype: 'textfield',
+                   listeners: { specialkey: 'onSpecialKey' },
+                   reference: 'from'
+               },
+               {
+                   fieldLabel: gettext('Receiver'),
+                   xtype: 'textfield',
+                   listeners: { specialkey: 'onSpecialKey' },
+                   reference: 'target'
+               },
+               {
+                   fieldLabel: gettext('Filter'),
+                   xtype: 'textfield',
+                   listeners: { specialkey: 'onSpecialKey' },
+                   reference: 'xfilter'
+               }
+           ]
+       },
+       {
+           width: 330,
+           border: false,
+           padding: 10,
+           layout: {
+               type: 'vbox',
+               align: 'stretch'
+           },
+           items: [
+               {
+                   fieldLabel: gettext('Start'),
+                   reference: 'starttime',
+                   listeners: { change: 'onFilterChange' },
+                   value: (function() {
+                       var now = new Date();
+                       return new Date(now.getTime() - 3600000);
+                   })(),
+                   xtype: 'promxoxDateTimeField'
+               },
+               {
+                   fieldLabel: gettext('End'),
+                   reference: 'endtime',
+                   listeners: { change: 'onFilterChange' },
+                   xtype: 'promxoxDateTimeField'
+               },
+               {
+                   layout: 'hbox',
+                   border: false,
+                   items: [
+                       {
+                           boxLabel: gettext('Include NDRs'),
+                           xtype: 'proxmoxcheckbox',
+                           listeners: { change: 'onFilterChange' },
+                           reference: 'ndr',
+                           name: 'ndrs'
+                       },
+                       {
+                           boxLabel: gettext('Include Greylist'),
+                           xtype: 'proxmoxcheckbox',
+                           listeners: { change: 'onFilterChange' },
+                           margin: { left: 20 },
+                           reference: 'greylist',
+                           name: 'greylist'
+                       }
+                   ]
+               }
+           ]
+       }
+    ]
+});
+
+Ext.define('PMG.MaiLogWindow', {
+    extend: 'Ext.window.Window',
+    xtype: 'pmgMaiLogWindow',
+
+    title: gettext('Syslog'),
+
+    logid: undefined,
+    starttime: undefined,
+    endtime: undefined,
+
+    width: 1024,
+    height: 400,
+    scrollable: true,
+
+    layout: 'auto',
+    modal: true,
+    bodyPadding: 5,
+
+    load: function() {
+       var me = this;
+
+       Proxmox.Utils.API2Request({
+           method: 'GET',
+           params: { starttime: me.starttime, endtime: me.endtime },
+           url: '/nodes/' + Proxmox.NodeName + '/tracker/' + me.logid,
+           waitMsgTarget: me,
+           failure: function(response, opts) {
+               me.update(gettext('Error') + " " + response.htmlStatus);
+           },
+           success: function(response, opts) {
+               var data = response.result.data;
+
+               var logs = "<pre style='margin: 0;'>";
+               Ext.Array.each(data.logs, function(line) {
+                   logs += Ext.htmlEncode(line) + "\n";
+               });
+               logs += "</pre>";
+               me.update(logs);
+           }
+       });
+    },
+
+    initComponent : function() {
+       var me = this;
+
+       if (!me.logid) {
+           throw "no logid specified";
+       }
+
+       if (!me.starttime) {
+           throw "no starttime specified";
+       }
+       if (!me.endtime) {
+           throw "no endtime specified";
+       }
+
+       me.callParent();
+
+       me.setHtml('Loading...');
+       me.load();
+    }
+});
+
+Ext.define('PMG.MailTracker', {
+    extend: 'Ext.grid.GridPanel',
+    xtype: 'pmgMailTracker',
+
+    title: gettext('Tracking Center'),
+
+    border: false,
+
+    emptyText: gettext('No data in database.'),
+    viewConfig: {
+       deferEmptyText: false
+    },
+
+    store: {
+       autoDestroy: true,
+       model: 'pmg-mail-tracker'
+    },
+
+    controller: {
+
+        xclass: 'Ext.app.ViewController',
+
+       onSearch: function() {
+           var view = this.getView();
+           var filter = this.lookupReference('filter');
+           var status = this.lookupReference('status');
+           var params = filter.getFilterParams();
+           status.update(''); // clear status before load
+           view.store.proxy.setExtraParams(params);
+           view.store.proxy.setUrl('/api2/json/nodes/' + Proxmox.NodeName + '/tracker');
+           view.store.load(function(records, operation, success) {
+               var response = operation.getResponse();
+               if (success) {
+                   // fixme: howto avoid duplicate Ext.decode ?
+                   var result = Ext.decode(response.responseText);
+                   if (result.changes) {
+                       status.update(result.changes);
+                   }
+               }
+           });
+       },
+
+       showDetails: function() {
+           var view = this.getView();
+           var sm = view.getSelectionModel();
+           var rec = sm.getSelection()[0];
+           if (!rec) {
+               return;
+           }
+
+           var params = view.store.proxy.getExtraParams();
+
+           var win = Ext.create('PMG.MaiLogWindow', {
+               starttime: params.starttime,
+               endtime: params.endtime,
+               logid: rec.data.id
+           });
+           win.show();
+       }
+    },
+
+    dockedItems: [
+       {
+           xtype: 'pmgMailTrackerFilter',
+           reference: 'filter',
+           listeners:  { filterChanged: 'onSearch' },
+           border: false,
+           dock: 'top'
+       },
+       {
+           xtype: 'toolbar',
+           items: [
+               { text: 'Search', handler: 'onSearch' },
+               { xtype: 'component', html: '', reference: 'status' }
+           ]
+       }
+    ],
+
+    columns: [
+       {
+           xtype: 'datecolumn',
+           header: gettext('Time'),
+           width: 120,
+           dataIndex: 'time',
+           format: 'M d H:i:s'
+       },
+       {
+           header: gettext('From'),
+           flex: 1,
+           dataIndex: 'from'
+       },
+       {
+           header: gettext('To'),
+           flex: 1,
+           dataIndex: 'to'
+       },
+       {
+           header: gettext('Status'),
+           width: 150,
+           renderer: function(v, metaData, rec) {
+               var rstatus = rec.data.rstatus;
+               if (v !== undefined && v !== '') {
+                   vtext = PMG.Utils.mail_status_map[v] || v;
+                   if (rstatus !== undefined && rstatus !== '') {
+                       rtext = PMG.Utils.mail_status_map[rstatus] || rstatus;
+                       return vtext + '/' + rtext;
+                   }
+                   if (rec.data.qid !== undefined) {
+                       return 'queued/' + vtext;
+                   }
+                   return vtext;
+               }
+               return 'unknown';
+           },
+           dataIndex: 'dstatus'
+       },
+       {
+           header: gettext('Size'),
+           hidden: true,
+           dataIndex: 'size'
+       },
+       {
+           header: 'MSGID',
+           width: 300,
+           hidden: true,
+           dataIndex: 'msgid'
+       },
+       {
+           header: gettext('Client'),
+           width: 200,
+           hidden: true,
+           dataIndex: 'client'
+       }
+    ],
+
+    listeners: {
+       itemdblclick: 'showDetails',
+    },
+
+    initComponent: function() {
+       var me = this;
+
+       me.callParent();
+
+       Proxmox.Utils.monStoreErrors(me.getView(), me.store);
+    }
+});
index 919b86864fb5f9035e138d6e6805d56507426f2c..f97ce6f70bd1239fa39439a691a991ee401d3f9b 100644 (file)
@@ -25,6 +25,7 @@ JSSRC=                                                        \
        QuarantineView.js                               \
        Dashboard.js                                    \
        VersionInfo.js                                  \
+       MailTracker.js                                  \
        NavigationTree.js                               \
        RuleConfiguration.js                            \
        SystemOptions.js                                \
index 4298dabe566511577017e8f2a4c4465d5d05eb81..e3a0440db4678b260609bf38a890dc505f3afb32 100644 (file)
@@ -115,7 +115,7 @@ Ext.define('PMG.store.NavigationStore', {
                    {
                        text: gettext('Tracking Center'),
                        iconCls: 'fa fa-map-o',
-                       path: 'pmgTrackingCenter',
+                       path: 'pmgMailTracker',
                        leaf: true,
                    },
                    {
index 200a50ea93dc711d5018c9742ab1fd3036f6f898..4ee6c1515ecb42ef6dd6662975ee0c819154402b 100644 (file)
@@ -30,6 +30,17 @@ Ext.define('PMG.Utils', {
        to: '<span class="fa fa-fw fa-user-circle"></span> '
     },
 
+    mail_status_map: {
+       2: 'delivered',
+       4: 'deferred',
+       5: 'bounced',
+       N: 'rejected',
+       G: 'greylisted',
+       A: 'accepted',
+       B: 'blocked',
+       Q: 'quarantine'
+    },
+
     format_oclass: function(oclass) {
        var icon = PMG.Utils.oclass_icon[oclass] || '';
        var text = PMG.Utils.oclass_text[oclass] || oclass;