Sanding the application with 240er grid

This commit is contained in:
Aaron Fischer 2015-12-06 22:40:57 +01:00
parent a6a9a3efb4
commit e15f100944
11 changed files with 137 additions and 31 deletions

View file

@ -10,9 +10,7 @@ textarea {
} }
#cc-logo { #cc-logo {
float: left; width: 60px;
width: 200px;
margin-right: 30px;
} }
#head { #head {
@ -21,6 +19,12 @@ textarea {
margin-top: 20px; margin-top: 20px;
} }
#graph {
display: inherit;
margin: auto;
margin-top: 20px;
}
{% if cljs %} {% if cljs %}
@-moz-keyframes three-quarters-loader { @-moz-keyframes three-quarters-loader {

View file

@ -1,7 +1,38 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<img id="cc-logo" src="/img/cup.svg"> <div class="row">
<h1>ClojureCup 2015 entry</h1> <div class="span5">
<p>You can find me on Twitter: <a href="https://twitter.com/fu86">@fu86</a></p> <img id="cc-logo" class="pull-left" src="/img/cup.svg">
<p>The cource code of this application is located at GitHub: <a href="https://github.com/f0086/clojurecup2015-mailhead">f0086/clojurecup2015-mailhead</a></p> </div>
<div class="span7">
<h1>ClojureCup 2015 submission</h1>
<p>You can find me on Twitter: <a href="https://twitter.com/fu86">@fu86</a></p>
<p>The sourcecode of this application is located at GitHub: <a href="https://github.com/f0086/clojurecup2015-mailhead">f0086/clojurecup2015-mailhead</a></p>
<div class="alert alert-danger" role="alert">
Please keep in mind that this application is written in 48 hours during a
programming competition. The e-mail parser is still somehow unstable,
complex or not wellformed headers may not work. There are some e-mail
parsing libraries out there, but <strong>none</strong> of them work
properly. I've tried a lot, and after several hours of frustration I
decided to <a href="https://github.com/owainlewis/clojure-mail/pull/37">fix
one lib</a> and move on. The parser is still not very resilient and
malformed dates or broken "Received" header fields canot be handled
correct. This is an issue I am aware of, but don't had the time to write a
proper parser in this short amount of time.</div>
<h3>Ideas for future versions</h3>
<ul>
<li>Add a language flag to each server box, so the user sees exactly where
the e-mail crosses borders.</li>
<li>Ping the hosts and use the IP to query
the <a href="https://www.arin.net/resources/whoisrws/index.html">ARIN REST
Service</a> to display company names.</li>
<li>Show the MTA if given</li>
<li>Indicate servers which do spam-checks and antivirus-checks</li>
<li>Display how much time passes between sending the e-mail from one
server to tne next.</li>
</ul>
</div>
</div>
{% endblock %} {% endblock %}

View file

@ -3,7 +3,7 @@
<head> <head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8"> <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<META name="viewport" content="width=device-width, initial-scale=1"> <META name="viewport" content="width=device-width, initial-scale=1">
<title>Welcome to mailhead</title> <title>mailhead -- make e-mail header visible</title>
<!-- styles --> <!-- styles -->
{% style "/assets/bootstrap/css/bootstrap.min.css" %} {% style "/assets/bootstrap/css/bootstrap.min.css" %}
@ -30,12 +30,15 @@
</div> </div>
<div id="app-navbar" class="navbar-collapse collapse"> <div id="app-navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li {% ifequal page "home.html" %} class="active"{%endifequal%}><a href="{{servlet-context}}/">Home</a> </li> <li {% ifequal page "home.html" %}
class="active"{%endifequal%}><a href="{{servlet-context}}/">
<span class="glyphicon glyphicon-flash"></span>
Analyze</a></li>
<li> <li>
<a class="dropdown-toggle" data-toggle="dropdown" <a class="dropdown-toggle" data-toggle="dropdown"
href="#" role="button" aria-haspopup="true" href="#" role="button" aria-haspopup="true"
aria-expanded="false"> aria-expanded="false">
Try some examples<span class="caret"></span></a> <span class="glyphicon glyphicon-book"></span> Try some examples<span class="caret"></span></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="{{servlet-context}}/example/1">Example <li><a href="{{servlet-context}}/example/1">Example
#1 (simple)</a></li> #1 (simple)</a></li>
@ -47,7 +50,9 @@
#4 (misconfiguration)</a></li> #4 (misconfiguration)</a></li>
</ul> </ul>
</li> </li>
<li {% ifequal page "about.html" %} class="active"{%endifequal%}><a href="{{servlet-context}}/about">About</a></li> <li {% ifequal page "about.html" %}
class="active"{%endifequal%}><a href="{{servlet-context}}/about"><span class="glyphicon
glyphicon-info-sign"></span> About</a></li>
</ul> </ul>
</div> </div>
</div> </div>

View file

@ -5,18 +5,19 @@
<img id="head" src="img/head.png"> <img id="head" src="img/head.png">
</div> </div>
<div class="span9"> <div class="span9">
<p class="col-md-9">Use this form to analyze a e-mail. Just paste the whole e-mail <p class="col-md-9">Use this form to analyze e-mail headers. Just paste the whole e-mail
in <strong>raw mode</strong> here and hit the analyze button. The e-mail in "<strong>raw mode</strong>" here and hit the analyze button. The e-mail
will be analyzed and an visual representation will be generated. Use this will be analyzed and an visual representation will be generated. Use this
tool to find e-mail problems or to see which servers, locations and tool to find e-mail problems or to see which servers, locations and
companies the e-mail passed. This tool is intended for debugging e-mail companies the e-mail passed. The e-mail will not be stored on the server,
communication.</p> but please don't paste sensible information here, just leave out the body
of the e-mail.</p>
<form class="col-md-9" action="/analyze" method="post"> <form class="col-md-9" action="/analyze" method="post">
{% csrf-field %} {% csrf-field %}
<textarea class="form-control" name="mailheader" placeholder="Paste your e-mail in source format (with headers) here."></textarea><br> <textarea class="form-control" name="mailheader" placeholder="Paste your e-mail in source format (with headers) here."></textarea><br>
<input class="btn btn-success form-control" type="submit" name="send" <input class="btn btn-success form-control" type="submit" name="send"
value="Analyze the mail now!"> value="Analyze the e-mail now!">
</form> </form>
</div> </div>
</div> </div>

View file

@ -3,8 +3,14 @@
{% block content %} {% block content %}
<div class="row"> <div class="row">
<div class="span12"> <div class="span12">
<h1>Can't parse the given email</h1> {% if mailheader %}
<h1>Can't parse the given e-mail header</h1>
<p>Want to try some examples instead (choose from the menu above)?</p>
<pre>{{ mailheader }}</pre> <pre>{{ mailheader }}</pre>
{% else %}
<h1>Sorry, no data to analyze given.</h1>
<p>Please insert a header into the form and try again.</p>
{% endif %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View file

@ -3,11 +3,52 @@
{% block content %} {% block content %}
<div class="row"> <div class="row">
<div class="span12"> <div class="span12">
<h1>Results</h1> <h1>Result</h1>
<img src="/image/{{ token }}"> <p>The following diagram shows the different
servers as boxes. The arrows represent the communication between the
those servers. Below are some usefull details like the travel time of
the e-mail, software used and so on.</p>
<img id="graph" src="/image/{{ token }}">
<h2>The analyzed email</h2> <div class="panel panel-default">
<div class="panel-heading">Some interesting details about this e-mail</div>
<table class="table table-striped table-bordered table-hover">
<tbody>
<tr>
<td><strong>Sender</strong></td>
<td>{{ from }}</td>
</tr>
<tr>
<td><strong>Receiver</strong></td>
<td>{{ to }}</td>
</tr>
<tr>
<td><strong>Travel time</strong></td>
<td>
{% if traveltime %}
<span class="label label-{% if traveltime > 5 %}danger{% else
%}success{% endif %}">{{ traveltime }}</span> seconds
{% else %}
Timing is not accurate enough for measurement
{% endif %}
</td>
</tr>
{% if mailer %}
<tr>
<td><strong>Sender software</strong></td>
<td>{{ mailer }}</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
<br>
<h3>The analyzed e-mail header</h3>
<pre>{{ mailheader }}</pre> <pre>{{ mailheader }}</pre>
</div> </div>
</div> </div>

View file

@ -2,7 +2,7 @@ Return-Path: <support@tindie.zendesk.com>
X-Original-To: aaron@gridbag.net X-Original-To: aaron@gridbag.net
Delivered-To: aaron@gridbag.net Delivered-To: aaron@gridbag.net
Received: by remote.gridbag.net (Postfix, from userid 5001) Received: by remote.gridbag.net (Postfix, from userid 5001)
id 7CCDA132244DF; Mon, 13 Apr 2015 22:09:59 +0200 (CEST) id 7CCDA132244DF; Mon, 13 Apr 2015 22:09:59 +0200
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on
lvps83-169-3-141.dedicated.hosteurope.de lvps83-169-3-141.dedicated.hosteurope.de
X-Spam-Level: X-Spam-Level:

View file

@ -2,7 +2,7 @@ Return-Path: <xxxi.boenicke@gese-gmbh.de>
X-Original-To: aaron@gridbag.net X-Original-To: aaron@gridbag.net
Delivered-To: aaron@gridbag.net Delivered-To: aaron@gridbag.net
Received: by remote.gridbag.net (Postfix, from userid 5001) Received: by remote.gridbag.net (Postfix, from userid 5001)
id 220624E0B3B; Mon, 5 Oct 2015 11:00:57 +0200 (CEST) id 220624E0B3B; Mon, 5 Oct 2015 11:00:57 +0200
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on
lvps83-169-3-141.dedicated.hosteurope.de lvps83-169-3-141.dedicated.hosteurope.de
X-Spam-Level: X-Spam-Level:

View file

@ -2,7 +2,7 @@ Return-Path: <fabian@fingerle.hn>
X-Original-To: aaron@gridbag.net X-Original-To: aaron@gridbag.net
Delivered-To: aaron@gridbag.net Delivered-To: aaron@gridbag.net
Received: by remote.gridbag.net (Postfix, user 5001) Received: by remote.gridbag.net (Postfix, user 5001)
id 8BD7C132244E1; Tue, 2 Sep 2014 22:28:09 +0200 (CEST) id 8BD7C132244E1; Tue, 2 Sep 2014 22:28:09 +0200
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on
lvps83-169-3-141.dedicated.hosteurope.de lvps83-169-3-141.dedicated.hosteurope.de
X-Spam-Level: X-Spam-Level:

View file

@ -9,9 +9,12 @@
[javax.mail.internet MimeMessage] [javax.mail.internet MimeMessage]
[javax.mail Session])) [javax.mail Session]))
(defn received-headers [all-headers] (defn find-headers [all-headers needle]
(map #(first (vals %)) (map #(first (vals %))
(filter (fn [header] (= "Received" (first (keys header)))) all-headers))) (filter (fn [header] (= needle (first (keys header)))) all-headers)))
(defn received-headers [all-headers]
(find-headers all-headers "Received"))
(defn parse-received-headers [received-header] (defn parse-received-headers [received-header]
(let [datetime (st/trim (last (st/split received-header #";"))) (let [datetime (st/trim (last (st/split received-header #";")))

View file

@ -2,6 +2,7 @@
(:require [mailhead.layout :as layout] (:require [mailhead.layout :as layout]
[mailhead.visualize :as v] [mailhead.visualize :as v]
[mailhead.parser :as parser] [mailhead.parser :as parser]
[clj-time.core :as time]
[compojure.core :refer [defroutes GET POST]] [compojure.core :refer [defroutes GET POST]]
[ring.util.response :refer [redirect]] [ring.util.response :refer [redirect]]
[ring.util.http-response :refer [ok content-type]] [ring.util.http-response :refer [ok content-type]]
@ -13,15 +14,29 @@
(defn about-page [] (defn about-page []
(layout/render "about.html")) (layout/render "about.html"))
;; TODO: Show more information (mail round trip time, ...) (defn find-header [parsed-email header]
(let [headers (:headers parsed-email)]
(first (parser/find-headers headers header))))
(defn calculate-travel-time [parsed-email-headers]
(let [start-date (:time (first (reverse parsed-email-headers)))
end-date (:time (last (reverse parsed-email-headers)))]
(if (time/after? end-date start-date)
(time/in-seconds (time/interval start-date end-date))
nil)))
(defn show-result [message-string] (defn show-result [message-string]
(if (empty? (parser/parse message-string)) (if (empty? (parser/parse message-string))
(layout/render "parser-error.html" {:mailheader message-string}) (layout/render "parser-error.html" {:mailheader message-string})
(let [parsed-email (parser/parse message-string) (let [parsed-email (parser/parse-all message-string)
token (v/draw parsed-email)] parsed-email-headers (parser/parse message-string)
token (v/draw parsed-email-headers)]
(layout/render "result.html" (layout/render "result.html"
{:mailheader message-string {:mailheader message-string
:email parsed-email :from (:address (first (:from parsed-email)))
:to (:address (first (:to parsed-email)))
:mailer (find-header parsed-email "X-Mailer")
:traveltime (calculate-travel-time parsed-email-headers)
:token token})))) :token token}))))
(defn show-sample [index] (defn show-sample [index]