From ac47357f45cd1938a0a95bb21ac93260ec0bad68 Mon Sep 17 00:00:00 2001 From: tonio Date: Fri, 17 Sep 2010 17:17:40 +0200 Subject: [PATCH] new: tinymce replaced by ckeditor (personal choice) new: sending multipart/alternative messages when using the HTML editor (far from perfect...) --- .hgignore | 2 +- extensions/amavis_quarantine/views.py | 2 +- extensions/webmail/lib.py | 14 +++++++++---- extensions/webmail/templates/compose.html | 2 +- extensions/webmail/templates/index.html | 24 ++++++++++++++++------- extensions/webmail/views.py | 23 +++++++++++++++++++--- static/js/editor_config.js | 13 ++++++++++++ templates/common/email_listing.html | 2 +- templates/common/mailheaders.html | 2 +- templates/common/tinymce_textareas.js | 15 -------------- urls.py | 1 - 11 files changed, 65 insertions(+), 35 deletions(-) create mode 100644 static/js/editor_config.js delete mode 100644 templates/common/tinymce_textareas.js diff --git a/.hgignore b/.hgignore index 06861c4f7..814ef94af 100644 --- a/.hgignore +++ b/.hgignore @@ -1,4 +1,4 @@ .*~$ ^[^\.]+\.pyc static/tmp -static/ckeditor +static/js/ckeditor diff --git a/extensions/amavis_quarantine/views.py b/extensions/amavis_quarantine/views.py index 5fb2ca2d5..c96036953 100644 --- a/extensions/amavis_quarantine/views.py +++ b/extensions/amavis_quarantine/views.py @@ -86,7 +86,7 @@ WHERE quarantine.mail_id='%s' msg = email.message_from_string(content) links = request.GET.has_key("links") and request.GET["links"] or "0" mode = request.GET.has_key("mode") and request.GET["mode"] or "plain" - mail = SQLemail(msg, mode, links) + mail = SQLemail(msg, mformat=mode, links=links) return _render(request, "common/viewmail.html", { "headers" : mail.render_headers(), "mailbody" : mail.body diff --git a/extensions/webmail/lib.py b/extensions/webmail/lib.py index a7bbe25a1..323fef2c6 100644 --- a/extensions/webmail/lib.py +++ b/extensions/webmail/lib.py @@ -581,7 +581,7 @@ def find_images_in_body(body): Before sending a message in HTML format, it is necessary to find all img tags contained in the body in order to rewrite them. For - example, icons provided by tinyMCE are stored on the server + example, icons provided by CKeditor are stored on the server filesystem and not accessible from the outside. We must embark them as parts off the MIME message if we want recipients to display them correctly. @@ -589,21 +589,27 @@ def find_images_in_body(body): :param body: the HTML body to parse """ from email.mime.image import MIMEImage + from urlparse import urlparse + html = lxml.html.fromstring(body) parts = [] for tag in html.iter("img"): src = tag.get("src") - fname = os.path.basename(src) + o = urlparse(src) + dirname = os.path.dirname(o.path).replace(settings.MEDIA_URL, "") + fname = os.path.basename(o.path) cid = "%s@modoboa" % os.path.splitext(fname)[0] tag.set("src", "cid:%s" % cid) - path = "%s/%s" % (settings.MODOBOA_DIR, re.sub("\.\./", "", src)) + path = os.path.join(settings.MEDIA_ROOT, dirname, fname) fp = open(path, "rb") p = MIMEImage(fp.read()) fp.close() p["Content-ID"] = "<%s>" % cid ct = p["Content-Type"] - p.replace_header("Content-Type", '%s; name="%s"' % (ct, fname)) + p.replace_header("Content-Type", '%s; name="%s"' \ + % (ct, os.path.basename(fname))) + p["Content-Disposition"] = "inline" parts.append(p) return lxml.html.tostring(html), parts diff --git a/extensions/webmail/templates/compose.html b/extensions/webmail/templates/compose.html index 7f3a09022..eee1cc0a7 100644 --- a/extensions/webmail/templates/compose.html +++ b/extensions/webmail/templates/compose.html @@ -7,7 +7,7 @@ {% if body %} + {% else %} {% endif %} diff --git a/extensions/webmail/templates/index.html b/extensions/webmail/templates/index.html index 19f7d5a77..e3c142ec6 100644 --- a/extensions/webmail/templates/index.html +++ b/extensions/webmail/templates/index.html @@ -68,6 +68,20 @@ window.addEvent("resize", function(evt) { setDivHeight("id_body", $("mailheader").getSize().y, 0); }); + window.fireEvent("resize"); + + var editormode = resp.editor; + var editorid = "id_body"; + if (editormode == "html") { + var instance = CKEDITOR.instances[editorid]; + if (instance) { + CKEDITOR.remove(instance); + } + CKEDITOR.replace(editorid, { + customConfig: "{{ MEDIA_URL }}/js/editor_config.js", + height: $(editorid).getSize().y + }); + } $$("a[name=back]").addEvent("click", loadFolder); $$("a[name=sendmail]").addEvent("click", function(evt) { evt.stop(); @@ -86,15 +100,11 @@ current_anchor.update(); } }); - tinyMCE.triggerSave(); + if (editormode == "html") { + CKEDITOR.instances[editorid].updateElement(); + } $("composemail").send(); }); - if (resp.editor == "html") { - new Request({url: "{% url tinymce-js 'common' %}", - onSuccess: function(resp) { eval(resp); } - }).get(); - } - window.fireEvent("resize"); } loadCompose = function(event) { diff --git a/extensions/webmail/views.py b/extensions/webmail/views.py index 7f3d2c0a3..c3a607052 100644 --- a/extensions/webmail/views.py +++ b/extensions/webmail/views.py @@ -236,6 +236,16 @@ def render_compose(request, form, posturl, email=None, insert_signature=False): editor=editor) return HttpResponse(simplejson.dumps(ctx), mimetype="application/json") +def __html2plaintext(content): + html = lxml.html.fromstring(content) + plaintext = "" + for p in html.xpath("//text()"): + p = p.strip('\r\t\n') + if p == "": + continue + plaintext += p + "\n" + return plaintext + def send_mail(request, withctx=False, origmsg=None, posturl=None): form = ComposeMailForm(request.POST) error = None @@ -247,16 +257,23 @@ def send_mail(request, withctx=False, origmsg=None, posturl=None): subtype = parameters.get_user(request.user, "EDITOR") body = request.POST["id_body"] + charset = "utf-8" if subtype == "html": from email.mime.multipart import MIMEMultipart + msg = MIMEMultipart(_subtype="related") + submsg = MIMEMultipart(_subtype="alternative") + textbody = __html2plaintext(body) + submsg.attach(MIMEText(textbody.encode(charset), + _subtype="plain", _charset=charset)) body, images = find_images_in_body(body) - msg.attach(MIMEText(body.encode("utf-8"), _subtype=subtype, - _charset="utf-8")) + submsg.attach(MIMEText(body.encode(charset), _subtype=subtype, + _charset=charset)) + msg.attach(submsg) for img in images: msg.attach(img) else: - msg = MIMEText(body.encode("utf-8"), _subtype=subtype) + msg = MIMEText(body.encode(charset), _subtype=subtype) msg["Subject"] = request.POST["subject"] msg["From"] = request.POST["from_"] diff --git a/static/js/editor_config.js b/static/js/editor_config.js new file mode 100644 index 000000000..fca3ad26d --- /dev/null +++ b/static/js/editor_config.js @@ -0,0 +1,13 @@ +CKEDITOR.editorConfig = function(config) { + config.toolbar = "Modoboa"; + config.toolbar_Modoboa = [ + ['Bold','Italic','Underline'], + ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], + ['NumberedList','BulletedList','-','Outdent','Indent'], + ['Undo','Redo'], + ['Link','Unlink','Anchor','-','Smiley'], + ['TextColor','BGColor','-','Source'], + ['Font','FontSize'], + ['SpellChecker'] + ]; +}; \ No newline at end of file diff --git a/templates/common/email_listing.html b/templates/common/email_listing.html index da73e9d30..eb23499c1 100644 --- a/templates/common/email_listing.html +++ b/templates/common/email_listing.html @@ -4,7 +4,7 @@ {% block html_head %} - + {% block css %}{% endblock %}