mail_grabber 1.0.0.rc1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,86 @@
1
+ var MailGrabberDOM = {
2
+ /**
3
+ * Change which content (message part) should show. When the page is loading,
4
+ * the HTML content will be active and the others will be hidden. When we
5
+ * click on tab e.g. Plain Text then this content will be active and other
6
+ * hidden.
7
+ *
8
+ * @param {Object} event - which part we clicked
9
+ */
10
+ changeMessageContent: function(event) {
11
+ var messageTabs =
12
+ document
13
+ .querySelectorAll('[data-message-tab]');
14
+
15
+ var messageContents =
16
+ document
17
+ .querySelectorAll('[data-message-content]');
18
+
19
+ var clickedTabType = event.target.dataset.messageTab;
20
+
21
+ messageTabs.forEach(function(messageTab, index) {
22
+ messageTab.classList.remove('active');
23
+ messageContents[index].classList.remove('hide');
24
+
25
+ if(messageTab.dataset.messageTab === clickedTabType) {
26
+ messageTab.classList.add('active');
27
+ }
28
+
29
+ if(messageContents[index].dataset.messageContent !== clickedTabType) {
30
+ messageContents[index].classList.add('hide');
31
+ }
32
+ });
33
+ },
34
+
35
+ /**
36
+ * Create a clone from an element, e.g. template tag.
37
+ *
38
+ * @param {String} selector - which describe how to find the element
39
+ *
40
+ * @return {Object} the clone of the found element
41
+ */
42
+ cloneContent: function(selector) {
43
+ return document.querySelector(selector).content.cloneNode(true);
44
+ },
45
+
46
+ /**
47
+ * Show default background image instead of any content.
48
+ */
49
+ defaultBackground: function() {
50
+ var messageContent =
51
+ document
52
+ .querySelector('div[data-content-type=message-content]');
53
+
54
+ messageContent.innerHTML = '';
55
+
56
+ messageContent.style.background =
57
+ "url('" + messageContent.dataset.backgroundImage +
58
+ "') center center no-repeat";
59
+ messageContent.style.backgroundSize = '50%';
60
+ messageContent.style.opacity = '10%';
61
+ },
62
+
63
+ /**
64
+ * Delete all content (message list and message content as well),
65
+ * set default background and the infinite scroll params when we click on
66
+ * the Reload or Delete tabs.
67
+ */
68
+ deleteContent: function() {
69
+ MailGrabberVariables.lastMessageId = -1;
70
+ MailGrabberVariables.page = 1;
71
+ MailGrabberDOM.defaultBackground();
72
+
73
+ document
74
+ .querySelector('ul[data-content-type=message-list]')
75
+ .innerHTML = '';
76
+ },
77
+
78
+ /**
79
+ * Root path, which returns with the server's root path. It can be an empty
80
+ * string or a string. It depends on how the server is running (standalone
81
+ * or in Ruby on Rails).
82
+ */
83
+ rootPath: function() {
84
+ return document.querySelector('body').dataset.rootPath;
85
+ }
86
+ };
@@ -0,0 +1,36 @@
1
+ var MailGrabberMessageAttachment = {
2
+ /**
3
+ * Render message attachment. Show the list of attachments at the top of the
4
+ * message content.
5
+ *
6
+ * @param {Object} messageAttachments - the message attachments container
7
+ * @param {Object} messagePart - a message part which we loaded
8
+ */
9
+ render: function(messageAttachments, messagePart) {
10
+ var messageAttachment = document.createElement('a');
11
+ var fileSize = document.createElement('span');
12
+ var messageAttachmentTemplate =
13
+ MailGrabberDOM
14
+ .cloneContent(
15
+ 'template[data-content-type=message-attachment-template]'
16
+ );
17
+
18
+ messageAttachment.href =
19
+ 'data:' + messagePart.mime_type + ';base64,' + messagePart.body;
20
+ messageAttachment.download = messagePart.filename;
21
+ messageAttachment.innerHTML = messagePart.filename;
22
+ messageAttachment.classList.add('color-black', 'no-text-decoration');
23
+
24
+ fileSize.innerHTML = MailGrabberUtilities.formatSize(messagePart.size);
25
+ fileSize.classList.add('color-gray', 'font-size-0_9', 'padding-left-10');
26
+
27
+ [messageAttachment, fileSize].forEach(function(node) {
28
+ messageAttachmentTemplate
29
+ .querySelector('li[data-content-type=message-attachment]')
30
+ .appendChild(node);
31
+ });
32
+
33
+ messageAttachments.classList.remove('hide');
34
+ messageAttachments.appendChild(messageAttachmentTemplate);
35
+ }
36
+ };
@@ -0,0 +1,114 @@
1
+ var MailGrabberMessageContent = {
2
+ /**
3
+ * Fill up the message content template with content.
4
+ *
5
+ * @param {Object} response - from the server with data
6
+ *
7
+ * @return {Object} the filled up template
8
+ */
9
+ fillUpTemplateWith: function(response) {
10
+ var message = response.message;
11
+ var messageParts = response.message_parts;
12
+ var messageContentTemplate =
13
+ MailGrabberDOM
14
+ .cloneContent('template[data-content-type=message-content-template]');
15
+
16
+ messageContentTemplate
17
+ .querySelector('div[data-content-type=message-subject]')
18
+ .innerHTML = message.subject;
19
+
20
+ MailGrabberMessageMetadata.render(
21
+ messageContentTemplate
22
+ .querySelector('dl[data-content-type=metadata]'),
23
+ message
24
+ );
25
+
26
+ messageContentTemplate
27
+ .querySelector('time[data-content-type=message-sent-at]')
28
+ .innerHTML = MailGrabberUtilities.formatDateTime(message.created_at);
29
+
30
+ messageContentTemplate
31
+ .querySelectorAll('[data-message-tab]')
32
+ .forEach(function(tab) {
33
+ tab.addEventListener('click', MailGrabberDOM.changeMessageContent);
34
+ });
35
+
36
+ messageContentTemplate
37
+ .querySelector('li[data-content-type=message-delete-tab]')
38
+ .addEventListener('click', function() {
39
+ MailGrabberApplication.deleteMessage(message.id);
40
+ });
41
+
42
+ messageContentTemplate
43
+ .querySelector('li[data-content-type=message-close-tab]')
44
+ .addEventListener('click', MailGrabberDOM.defaultBackground);
45
+
46
+ messageParts.forEach(function(messagePart) {
47
+ if(messagePart.is_attachment === 0 && messagePart.is_inline === 0) {
48
+ switch(messagePart.mime_type) {
49
+ case 'text/html':
50
+ MailGrabberVariables.messageHasHtmlPart = true;
51
+ MailGrabberMessageHtmlPart.render(
52
+ messageContentTemplate
53
+ .querySelector('iframe[data-content-type=message-html-body]'),
54
+ messageParts,
55
+ messagePart.body
56
+ );
57
+
58
+ break;
59
+ case 'text/plain':
60
+ messageContentTemplate
61
+ .querySelector('pre[data-content-type=message-text-body]')
62
+ .innerText = messagePart.body;
63
+
64
+ break;
65
+ }
66
+ } else if(messagePart.is_attachment === 1 &&
67
+ messagePart.is_inline === 0) {
68
+ MailGrabberMessageAttachment.render(
69
+ messageContentTemplate
70
+ .querySelector('ul[data-content-type=message-attachments]'),
71
+ messagePart
72
+ );
73
+ }
74
+ });
75
+
76
+ messageContentTemplate
77
+ .querySelector('pre[data-content-type=message-raw-body]')
78
+ .innerText = message.raw;
79
+
80
+ return messageContentTemplate;
81
+ },
82
+
83
+ /**
84
+ * Render the content of the message (all parts, inline attachments and
85
+ * attachments). Also, it sets up event listeners of the HTML, PlainText,
86
+ * Raw, Delete and Close tabs.
87
+ *
88
+ * @param {Object} response - the response of the get message request
89
+ */
90
+ render: function(response) {
91
+ var messageContent =
92
+ document
93
+ .querySelector('div[data-content-type=message-content]');
94
+
95
+ messageContent.removeAttribute('style');
96
+ messageContent.innerHTML = '';
97
+
98
+ MailGrabberVariables.messageHasHtmlPart = false;
99
+
100
+ messageContent.appendChild(
101
+ MailGrabberMessageContent.fillUpTemplateWith(response)
102
+ );
103
+
104
+ if(!MailGrabberVariables.messageHasHtmlPart) {
105
+ messageContent
106
+ .querySelector('li[data-message-tab=text]')
107
+ .click();
108
+
109
+ messageContent
110
+ .querySelector('li[data-message-tab=html]')
111
+ .classList.add('hide');
112
+ }
113
+ }
114
+ };
@@ -0,0 +1,26 @@
1
+ var MailGrabberMessageHtmlPart = {
2
+ /**
3
+ * Render the HTML part of the message. If the message has inline images,
4
+ * then it will render those images as well. An iframe will contain this
5
+ * content.
6
+ *
7
+ * @param {Object} iFrame - the iframe HTML tag
8
+ * @param {Object} messageParts - the parts of the message
9
+ * @param {Object} messageHtmlPart - the HTML part of the message
10
+ */
11
+ render: function(iFrame, messageParts, messageHtmlPart) {
12
+ var messageInlineAttachmentRegExp = new RegExp('cid:');
13
+
14
+ if(messageInlineAttachmentRegExp.test(messageHtmlPart)) {
15
+ messageHtmlPart =
16
+ MailGrabberMessageInlineAttachments.render(
17
+ messageParts, messageHtmlPart
18
+ );
19
+ }
20
+
21
+ iFrame.srcdoc = messageHtmlPart;
22
+ iFrame.onload = function() {
23
+ iFrame.height = iFrame.contentDocument.body.scrollHeight + 65;
24
+ }
25
+ }
26
+ };
@@ -0,0 +1,21 @@
1
+ var MailGrabberMessageInlineAttachments = {
2
+ /**
3
+ * Render inline images of the message. Change the cid:something12345 with
4
+ * the encoded image content.
5
+ *
6
+ * @param {Object} messageParts - the parts of the message
7
+ * @param {Object} messageHtmlPart - the HTML part of the message
8
+ *
9
+ * @return {Object} messageHtmlPart - the modified HTML part of the message
10
+ */
11
+ render: function(messageParts, messageHtmlPart) {
12
+ messageParts.forEach(function(messagePart) {
13
+ if(messagePart.is_attachment === 1 && messagePart.is_inline === 1) {
14
+ messageHtmlPart = messageHtmlPart.replace('cid:' + messagePart.cid,
15
+ 'data:' + messagePart.mime_type + ';base64,' + messagePart.body);
16
+ }
17
+ });
18
+
19
+ return messageHtmlPart;
20
+ }
21
+ };
@@ -0,0 +1,54 @@
1
+ var MailGrabberMessageList = {
2
+ /**
3
+ * Fill up the message list template with content.
4
+ *
5
+ * @param {Object} message
6
+ *
7
+ * @return {Object} the filled up template
8
+ */
9
+ fillUpTemplateWith: function(message) {
10
+ var messageListTemplate =
11
+ MailGrabberDOM
12
+ .cloneContent('template[data-content-type=message-list-template]');
13
+
14
+ messageListTemplate
15
+ .querySelector('li')
16
+ .addEventListener('click', function() {
17
+ MailGrabberApplication.getMessage(message.id);
18
+ });
19
+
20
+ messageListTemplate
21
+ .querySelector('div[data-content-type=message-senders]')
22
+ .innerHTML = message.senders;
23
+
24
+ messageListTemplate
25
+ .querySelector('time[data-content-type=message-sent-at]')
26
+ .innerHTML =
27
+ MailGrabberUtilities
28
+ .formatDateTime(message.created_at, 'messageListDateOrTime');
29
+
30
+ messageListTemplate
31
+ .querySelector('div[data-content-type=message-subject]')
32
+ .innerHTML = message.subject;
33
+
34
+ return messageListTemplate;
35
+ },
36
+
37
+ /**
38
+ * Render the list of the messages. Also add event listener when click on a
39
+ * message then it will load that content.
40
+ *
41
+ * @param {Object} messages - the list of the given message.
42
+ */
43
+ render: function(messages) {
44
+ var messageList =
45
+ document
46
+ .querySelector('ul[data-content-type=message-list]');
47
+
48
+ messages.forEach(function(message) {
49
+ messageList.appendChild(
50
+ MailGrabberMessageList.fillUpTemplateWith(message)
51
+ );
52
+ });
53
+ }
54
+ };
@@ -0,0 +1,23 @@
1
+ var MailGrabberMessageMetadata = {
2
+ /**
3
+ * Render senders and recipients data of the message.
4
+ *
5
+ * @param {Object} messageMetadata - the metadata container
6
+ * @param {Object} message - the requested message
7
+ */
8
+ render: function(messageMetadata, message) {
9
+ var metadata =
10
+ '<dt>From:</dt><dd>' + message.senders + '</dd>' +
11
+ '<dt>To:</dt><dd>' + message.recipients + '</dd>';
12
+
13
+ if(message.carbon_copy) {
14
+ metadata += '<dt>Cc:</dt><dd>' + message.carbon_copy + '</dd>';
15
+ }
16
+
17
+ if(message.blind_carbon_copy) {
18
+ metadata += '<dt>Bcc:</dt><dd>' + message.blind_carbon_copy + '</dd>';
19
+ }
20
+
21
+ messageMetadata.innerHTML = metadata;
22
+ }
23
+ };
@@ -0,0 +1,65 @@
1
+ var MailGrabberUtilities = {
2
+ /**
3
+ * Format the given date or time.
4
+ *
5
+ * @param {DateTime} dateTime - the message created at attribute
6
+ * @param {String} ouputType - what type we would like to see
7
+ *
8
+ * @return {String} the new format of the date or time
9
+ */
10
+ formatDateTime: function(dateTime, outputType) {
11
+ dateTime = new Date(dateTime);
12
+ var dateTimeNow = new Date();
13
+ // Sun Feb 21 2021 21:00:00 GMT+0100 (Central European Standard Time)
14
+ // 0 1 2 3 4 5 6 7 8 9
15
+ var dateTimeComponents = dateTime.toString().split(' ');
16
+ var output;
17
+
18
+ switch(outputType) {
19
+ case 'messageListDateOrTime':
20
+ if(dateTime.getDate() === dateTimeNow.getDate()) {
21
+ output = MailGrabberUtilities.formatTime(dateTimeComponents[4]);
22
+ } else if(dateTime.getFullYear() === dateTimeNow.getFullYear()) {
23
+ output = dateTimeComponents[1] + ' ' + dateTimeComponents[2];
24
+ } else {
25
+ output = dateTimeComponents[3] + ' ' + dateTimeComponents[1] + ' ' +
26
+ dateTimeComponents[2];
27
+ }
28
+
29
+ break;
30
+ default:
31
+ output = dateTimeComponents[3] + ' ' + dateTimeComponents[1] + ' ' +
32
+ dateTimeComponents[2] + ' - ' +
33
+ MailGrabberUtilities.formatTime(dateTimeComponents[4]);
34
+ }
35
+
36
+ return output;
37
+ },
38
+
39
+ /**
40
+ * Format the given number (attachment size).
41
+ *
42
+ * @param {Number} size - the size of the attachment in bytes
43
+ *
44
+ * @return {String} the formatted number with unit
45
+ */
46
+ formatSize: function(size) {
47
+ var exponent = (Math.log(size) / Math.log(1024)) | 0;
48
+ var number = +(size / Math.pow(1024, exponent)).toFixed(1);
49
+
50
+ return number + ' ' + ('KMGTPEZY'[exponent - 1] || '') + 'B';
51
+ },
52
+
53
+ /**
54
+ * Format the given time.
55
+ *
56
+ * @param {String} time
57
+ *
58
+ * @return {String} the new format of the time
59
+ */
60
+ formatTime: function(time) {
61
+ var timeComponents = time.split(':');
62
+
63
+ return timeComponents[0] + ':' + timeComponents[1];
64
+ }
65
+ };
@@ -0,0 +1,24 @@
1
+ var MailGrabberVariables = {
2
+ /**
3
+ * The last message id what loaded. If it is -1 then we have no any
4
+ * messages.
5
+ */
6
+ lastMessageId: -1,
7
+
8
+ /**
9
+ * The message has HTML part or not.
10
+ */
11
+ messageHasHtmlPart: false,
12
+
13
+ /**
14
+ * The message is list reloading or not (click on the Reload tab).
15
+ */
16
+ messageListReloading: false,
17
+
18
+ /**
19
+ * Params that we can follow how many messages we have on the list. We are
20
+ * loading 15 messages in every request.
21
+ */
22
+ page: 1,
23
+ perPage: 15
24
+ };
@@ -0,0 +1,6 @@
1
+ (function() {
2
+ /**
3
+ * When DOM loaded, then call MailGrabber's init function.
4
+ */
5
+ document.addEventListener('DOMContentLoaded', MailGrabberApplication.init);
6
+ })();
@@ -11,6 +11,16 @@
11
11
  <link rel="stylesheet" href="<%= root_path %>/stylesheets/application.css" type="text/css" charset="utf-8">
12
12
 
13
13
  <script src="<%= root_path %>/javascripts/application.js"></script>
14
+ <script src="<%= root_path %>/javascripts/dom.js"></script>
15
+ <script src="<%= root_path %>/javascripts/message_attachment.js"></script>
16
+ <script src="<%= root_path %>/javascripts/message_content.js"></script>
17
+ <script src="<%= root_path %>/javascripts/message_html_part.js"></script>
18
+ <script src="<%= root_path %>/javascripts/message_inline_attachments.js"></script>
19
+ <script src="<%= root_path %>/javascripts/message_list.js"></script>
20
+ <script src="<%= root_path %>/javascripts/message_metadata.js"></script>
21
+ <script src="<%= root_path %>/javascripts/utilities.js"></script>
22
+ <script src="<%= root_path %>/javascripts/variables.js"></script>
23
+ <script src="<%= root_path %>/javascripts/web.js"></script>
14
24
  </head>
15
25
 
16
26
  <body data-root-path="<%= root_path %>">
@@ -14,7 +14,8 @@ module MailGrabber
14
14
  module Web
15
15
  module_function
16
16
 
17
- # Method which build a Rack application and run the Web::Application
17
+ # Method which build a Rack application and run the
18
+ # MailGrabber::Web::Application.
18
19
  def app
19
20
  @app ||= Rack::Builder.new do
20
21
  use Rack::Static,
data/lib/mail_grabber.rb CHANGED
@@ -3,6 +3,6 @@
3
3
  require 'mail_grabber/error'
4
4
  require 'mail_grabber/database_helper'
5
5
  require 'mail_grabber/delivery_method'
6
- # If we are using this gem outside of Rails then do not load this code.
6
+ # If we are using this gem outside of Rails, then do not load this code.
7
7
  require 'mail_grabber/railtie' if defined?(Rails)
8
8
  require 'mail_grabber/version'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mail_grabber
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Norbert Szivós
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-20 00:00:00.000000000 Z
11
+ date: 2022-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mail
@@ -78,6 +78,16 @@ files:
78
78
  - lib/mail_grabber/web/application_router.rb
79
79
  - lib/mail_grabber/web/assets/images/mail_grabber515x500.png
80
80
  - lib/mail_grabber/web/assets/javascripts/application.js
81
+ - lib/mail_grabber/web/assets/javascripts/dom.js
82
+ - lib/mail_grabber/web/assets/javascripts/message_attachment.js
83
+ - lib/mail_grabber/web/assets/javascripts/message_content.js
84
+ - lib/mail_grabber/web/assets/javascripts/message_html_part.js
85
+ - lib/mail_grabber/web/assets/javascripts/message_inline_attachments.js
86
+ - lib/mail_grabber/web/assets/javascripts/message_list.js
87
+ - lib/mail_grabber/web/assets/javascripts/message_metadata.js
88
+ - lib/mail_grabber/web/assets/javascripts/utilities.js
89
+ - lib/mail_grabber/web/assets/javascripts/variables.js
90
+ - lib/mail_grabber/web/assets/javascripts/web.js
81
91
  - lib/mail_grabber/web/assets/stylesheets/application.css
82
92
  - lib/mail_grabber/web/views/_message_attachment_template.html.erb
83
93
  - lib/mail_grabber/web/views/_message_content_template.html.erb
@@ -91,7 +101,8 @@ metadata:
91
101
  source_code_uri: https://github.com/MailToolbox/mail_grabber
92
102
  changelog_uri: https://github.com/MailToolbox/mail_grabber/blob/main/CHANGELOG.md
93
103
  bug_tracker_uri: https://github.com/MailToolbox/mail_grabber/issues
94
- documentation_uri: https://rubydoc.info/gems/mail_grabber
104
+ documentation_uri: https://rubydoc.info/github/MailToolbox/mail_grabber/main
105
+ rubygems_mfa_required: 'true'
95
106
  post_install_message:
96
107
  rdoc_options: []
97
108
  require_paths:
@@ -100,14 +111,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
111
  requirements:
101
112
  - - ">="
102
113
  - !ruby/object:Gem::Version
103
- version: 2.5.0
114
+ version: 2.7.0
104
115
  required_rubygems_version: !ruby/object:Gem::Requirement
105
116
  requirements:
106
- - - ">"
117
+ - - ">="
107
118
  - !ruby/object:Gem::Version
108
- version: 1.3.1
119
+ version: '0'
109
120
  requirements: []
110
- rubygems_version: 3.1.4
121
+ rubygems_version: 3.3.3
111
122
  signing_key:
112
123
  specification_version: 4
113
124
  summary: Grab mails to inspect with MailGrabber.