MailHog/assets/js/controllers.js

265 lines
7.2 KiB
JavaScript
Raw Normal View History

2014-04-20 14:35:59 +00:00
var mailhogApp = angular.module('mailhogApp', []);
2014-04-27 17:19:30 +00:00
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
mailhogApp.controller('MailCtrl', function ($scope, $http, $sce, $timeout) {
$scope.cache = {};
2014-04-26 12:12:26 +00:00
$scope.previewAllHeaders = false;
2014-04-27 17:19:30 +00:00
$scope.eventsPending = {};
$scope.eventCount = 0;
$scope.eventDone = 0;
$scope.eventFailed = 0;
2014-04-27 22:38:43 +00:00
$scope.hasEventSource = false;
$scope.source = null;
$(function() {
2014-04-27 22:52:42 +00:00
$scope.openStream();
});
$scope.toggleStream = function() {
$scope.source == null ? $scope.openStream() : $scope.closeStream();
}
$scope.openStream = function() {
2014-04-27 22:38:43 +00:00
$scope.source = new EventSource('/api/v1/events');
$scope.source.addEventListener('message', function(e) {
$scope.$apply(function() {
$scope.messages.push(JSON.parse(e.data));
});
}, false);
$scope.source.addEventListener('open', function(e) {
$scope.$apply(function() {
$scope.hasEventSource = true;
});
}, false);
$scope.source.addEventListener('error', function(e) {
2014-04-27 22:52:42 +00:00
//if(e.readyState == EventSource.CLOSED) {
2014-04-27 22:38:43 +00:00
$scope.$apply(function() {
$scope.hasEventSource = false;
});
2014-04-27 22:52:42 +00:00
//}
2014-04-27 22:38:43 +00:00
}, false);
2014-04-27 22:52:42 +00:00
}
$scope.closeStream = function() {
$scope.source.close();
$scope.source = null;
$scope.hasEventSource = false;
}
2014-04-27 22:38:43 +00:00
2014-04-27 18:06:27 +00:00
$scope.startEvent = function(name, args, glyphicon) {
2014-04-27 17:19:30 +00:00
var eID = guid();
2014-04-27 23:21:57 +00:00
//console.log("Starting event '" + name + "' with id '" + eID + "'")
2014-04-27 17:19:30 +00:00
var e = {
id: eID,
name: name,
started: new Date(),
complete: false,
failed: false,
args: args,
2014-04-27 18:06:27 +00:00
glyphicon: glyphicon,
2014-04-27 17:19:30 +00:00
getClass: function() {
// FIXME bit nasty
if(this.failed) {
return "bg-danger"
}
if(this.complete) {
return "bg-success"
}
return "bg-warning"; // pending
},
done: function() {
//delete $scope.eventsPending[eID]
var e = this;
e.complete = true;
$scope.eventDone++;
if(this.failed) {
2014-04-27 23:21:57 +00:00
// console.log("Failed event '" + e.name + "' with id '" + eID + "'")
2014-04-27 17:19:30 +00:00
} else {
2014-04-27 23:21:57 +00:00
// console.log("Completed event '" + e.name + "' with id '" + eID + "'")
2014-04-27 17:34:28 +00:00
$timeout(function() {
e.remove();
}, 10000);
2014-04-27 17:19:30 +00:00
}
},
fail: function() {
$scope.eventFailed++;
this.failed = true;
this.done();
2014-04-27 17:34:28 +00:00
},
remove: function() {
2014-04-27 23:21:57 +00:00
// console.log("Deleted event '" + e.name + "' with id '" + eID + "'")
2014-04-27 17:34:28 +00:00
if(e.failed) {
$scope.eventFailed--;
}
delete $scope.eventsPending[eID];
$scope.eventDone--;
$scope.eventCount--;
return false;
2014-04-27 17:19:30 +00:00
}
};
$scope.eventsPending[eID] = e;
$scope.eventCount++;
return e;
}
2014-04-27 16:31:00 +00:00
2014-04-27 18:26:21 +00:00
$scope.messagesDisplayed = function() {
return $('#messages-container table tbody tr').length
}
2014-04-20 14:35:59 +00:00
$scope.refresh = function() {
2014-04-27 18:06:27 +00:00
var e = $scope.startEvent("Loading messages", null, "glyphicon-download");
2014-04-20 14:35:59 +00:00
$http.get('/api/v1/messages').success(function(data) {
$scope.messages = data;
2014-04-27 17:19:30 +00:00
e.done();
2014-04-20 14:35:59 +00:00
});
}
$scope.refresh();
$scope.selectMessage = function(message) {
if($scope.cache[message.Id]) {
$scope.preview = $scope.cache[message.Id];
2014-04-26 12:12:26 +00:00
reflow();
} else {
$scope.preview = message;
2014-04-27 18:06:27 +00:00
var e = $scope.startEvent("Loading message", message.Id, "glyphicon-download-alt");
$http.get('/api/v1/messages/' + message.Id).success(function(data) {
$scope.cache[message.Id] = data;
data.previewHTML = $sce.trustAsHtml($scope.getMessageHTML(data));
$scope.preview = data;
preview = $scope.cache[message.Id];
2014-04-26 12:12:26 +00:00
reflow();
2014-04-27 17:19:30 +00:00
e.done();
});
}
}
2014-04-26 12:12:26 +00:00
$scope.toggleHeaders = function(val) {
$scope.previewAllHeaders = val;
var t = window.setInterval(function() {
if(val) {
if($('#hide-headers').length) {
window.clearInterval(t);
reflow();
}
} else {
if($('#show-headers').length) {
window.clearInterval(t);
reflow();
}
}
}, 10);
}
2014-04-21 21:32:34 +00:00
$scope.getMessagePlain = function(message) {
2014-04-27 23:21:57 +00:00
var l = $scope.findMatchingMIME(message, "text/plain");
if(l != null && l !== "undefined") {
return l.Body;
}
return message.Content.Body;
2014-04-21 21:32:34 +00:00
}
2014-04-27 23:21:57 +00:00
$scope.findMatchingMIME = function(part, mime) {
// TODO cache results
2014-04-27 23:21:57 +00:00
if(part.MIME) {
for(var p in part.MIME.Parts) {
if("Content-Type" in part.MIME.Parts[p].Headers) {
if(part.MIME.Parts[p].Headers["Content-Type"].length > 0) {
if(part.MIME.Parts[p].Headers["Content-Type"][0].match(mime + ";?.*")) {
return part.MIME.Parts[p];
} else if (part.MIME.Parts[p].Headers["Content-Type"][0].match(/multipart\/.*/)) {
var f = $scope.findMatchingMIME(part.MIME.Parts[p], mime);
if(f != null) {
return f;
}
}
2014-04-26 11:16:57 +00:00
}
}
2014-04-27 23:21:57 +00:00
}
}
return null;
2014-04-21 21:32:34 +00:00
}
$scope.hasHTML = function(message) {
// TODO cache this
var l = $scope.findMatchingMIME(message, "text/html");
if(l != null && l !== "undefined") {
return true
}
return false;
}
2014-04-27 23:21:57 +00:00
$scope.getMessageHTML = function(message) {
var l = $scope.findMatchingMIME(message, "text/html");
if(l != null && l !== "undefined") {
return l.Body;
}
return "<HTML not found>";
}
2014-04-21 21:32:34 +00:00
2014-04-20 14:35:59 +00:00
$scope.date = function(timestamp) {
return (new Date(timestamp)).toString();
};
$scope.deleteAll = function() {
$('#confirm-delete-all').modal('show');
}
2014-04-27 16:31:00 +00:00
$scope.releaseOne = function(message) {
$scope.releasing = message;
$('#release-one').modal('show');
}
$scope.confirmReleaseMessage = function() {
$('#release-one').modal('hide');
var message = $scope.releasing;
$scope.releasing = null;
2014-04-27 18:06:27 +00:00
var e = $scope.startEvent("Releasing message", message.Id, "glyphicon-share");
2014-04-27 17:19:30 +00:00
2014-04-27 16:31:00 +00:00
$http.post('/api/v1/messages/' + message.Id + '/release', {
email: $('#release-message-email').val(),
host: $('#release-message-smtp-host').val(),
port: $('#release-message-smtp-port').val(),
}).success(function() {
2014-04-27 17:19:30 +00:00
e.done();
}).error(function(err) {
e.fail();
e.error = err;
2014-04-27 16:31:00 +00:00
});
}
2014-04-20 19:13:39 +00:00
$scope.getSource = function(message) {
var source = "";
$.each(message.Content.Headers, function(k, v) {
source += k + ": " + v + "\n";
});
source += "\n";
source += message.Content.Body;
return source;
}
2014-04-20 14:35:59 +00:00
$scope.deleteAllConfirm = function() {
$('#confirm-delete-all').modal('hide');
2014-04-27 18:06:27 +00:00
var e = $scope.startEvent("Deleting all messages", null, "glyphicon-remove-circle");
2014-04-27 19:52:46 +00:00
$http.delete('/api/v1/messages').success(function() {
2014-04-20 14:35:59 +00:00
$scope.refresh();
$scope.preview = null;
2014-04-27 17:19:30 +00:00
e.done()
2014-04-20 14:35:59 +00:00
});
}
$scope.deleteOne = function(message) {
2014-04-27 18:06:27 +00:00
var e = $scope.startEvent("Deleting message", message.Id, "glyphicon-remove");
2014-04-27 19:52:46 +00:00
$http.delete('/api/v1/messages/' + message.Id).success(function() {
2014-04-20 14:35:59 +00:00
if($scope.preview._id == message._id) $scope.preview = null;
$scope.refresh();
2014-04-27 17:19:30 +00:00
e.done();
2014-04-20 14:35:59 +00:00
});
}
2014-04-27 15:06:58 +00:00
});