I use blat.exe running from Powershell to generate e-mails with HTML. When I'm sending an e-mail to the Google domain everything is OK and code is generating fine. The headers and rest of code look like this:
<html xmlns=3D"http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8">
<title>My email</title>
</head>
...
<tr style=3D"height:15pt;">
<td style=3D"border: 1pt solid; border-color:black; padding-left:3.5pt=
; height: 15pt;">
...
But when I send the same e-mail to my client's domain, the HTML code look much different:
<html xmlns="ttp://www.w3.org/1999/xhtml""><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>My email</title>
</head>
...
<tr style="eight:15pt;"">
<td style="order:" 1ptsolid;border-color:black;padding-left:3.5pt;height:15pt;?="">
...
Do you have any ideas why in second option first letters after quotes are missing or why quotes at the end of the line are changed to "" or ?="? Spaces in style are missing too.
My blat command looks like this: ./blat.exe 'C:\path\file.html' -f alert#clientsdomain.com -server mail.clients.server.addr -to 'my_email#google.com,other_email#clientsdomain.com' -subject 'email title' -html
Thanks in advance for any tips!
I found neither the reason nor the exact solution but I have some workaround.
I used just Powershell with a simple command and it worked:
$body= Get-Content "C:\path_to_html_file\file.html" | out-string
Send-MailMessage -From "alert#clientsdomain.com" -to 'my_email#google.com', 'other_email#clientsdomain.com' -Subject "email title" -Body $body -BodyASHtml -SmtpServer "mail.clients.server.addr" -Encoding ([System.Text.Encoding]::UTF8)
Related
I have a folder in a ftp with a hundred of subfolders, each have it's own index.html
I want to add a <link rel="stylesheet" href="https://subdomain.domain.fr/vad/client/build/iconfont.css">
in each index.html
The subdomain is variable and can be captured from another stylesheet link ex :
<link rel="stylesheet" href="https://subdomain.domain.fr/vad/client/build/theme.css">
I tried this :
find . -type f -name index.html -exec sed -i 's/<link rel="stylesheet" href="https:\/\/\(*\).domain.fr\/vad\/client\/build\/theme.css">/<link rel="stylesheet" href="https:\/\/\1.domain.fr\/vad\/client\/build\/theme.css"><link rel="stylesheet" href="https:\/\/\1.domain.fr\/vad\/client\/build\/iconfont.css">/g' {} \;
With capturing and copy groups but it's not working
For ease and readability, change the delimiter from / to let's say # You also have to escape real dots in search pattern…
sed -i 's#<link rel="stylesheet" href="https://\(*\)\.domain\.fr/vad/client/build/theme\.css">#<link rel="stylesheet" href="https://\1.domain.fr/vad/client/build/theme.css"><link rel="stylesheet" href="https://\1.domain.fr/vad/client/build/iconfont.css">#g'
From there, I can see there's a mistake in your regexp capturing group… You wrote \(*\), but I suspect you mean \(.*\) :) (otherwise, you where trying to capture nothing …or by chance opening parenthesis only…)
Now, it's look like you are replacing one word with another one, in order to change the CSS file? As it's appearing in a specific kind of line, you can perform a simple replacement in line matching that pattern ;)
sed -i '/\<link rel="stylesheet" href="https:\/\/.*\.domain\.fr\/vad\/client\/build/s#theme#iconfont#'
Using Perl and a Mojo::DOM HTML Parser to edit your HTML:
use strict; use warnings;
use Mojo::DOM;
# Slurp the whole HTML as string
my $html = join "", <>;
my $dom = Mojo::DOM->new($html);
# Fetch domain name
$_ = $dom
->find('link[href][rel="stylesheet"]')
->map(attr => 'href')
->last;
my ($domain) = m|^https?://([^/]+)/|
or die "No match https?!\n";
# Find/append
$dom
->find('head > link[href][rel="stylesheet"]')
->last
->append(
"\n" .
'<link rel="stylesheet" href="https://' .
$domain .
'/build/iconfont.css" />'
);
# Render
print "$dom";
Output
Example of one file:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="fr" xml:lang="fr" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<link href="https://subdomain.domain.fr/build/theme.css" rel="stylesheet">
<link href="https://subdomain.domain.fr/build/iconfont.css" rel="stylesheet">
<title></title>
</head>
<body>
POUET
</body>
</html>
Usage
First test the script against some files without sponge.
Then, if tests are satisfactory:
#!/bin/bash
shopt -s globstar # enable recursion **
for h in **/*.html; do
perl Mojo::DOM.pl "$h" | sponge "$h"
done
I would like to display a simple HTML page in a PowerShell dialog box.
This is the way to build a dialog with dialog.ps1:
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$objForm = New-Object System.Windows.Forms.Form
[void] $objForm.ShowDialog()
In this windows I would like to display a webpage like index.html:
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
Hello world!
</body>
</html>
Of course, the webpage has a little more elements, like a picture with picturemap.
If this would work with CMD too, I would like this option even more.
The following snippet - which uses PSv5+[1] syntax for convenience - demonstrates use of the WebBrowser control to display HTML text in a WinForms dialog:
# PSv5+:
# Import namespaces so that types can be referred by
# their mere name (e.g., `Form` rather than `System.Windows.Forms.Form`)
#
using namespace System.Windows.Forms
using namespace System.Drawing
# Load the WinForms assembly.
Add-Type -AssemblyName System.Windows.Forms
# Create a form.
$form = [Form] #{
ClientSize = [Point]::new(400, 400)
Text = "WebBrowser-Control Demo"
}
# Create a web-browser control, make it as large as the inside of the form,
# and assign the HTML text.
$sb = [WebBrowser] #{
ClientSize = $form.ClientSize
DocumentText = #'
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
</head>
<body>
Hello world!
</body>
</html>
'#
}
# Add the web-browser control to the form...
$form.Controls.Add($sb)
# ... and display the form as a dialog (synchronously).
$form.ShowDialog()
# Clean up.
$form.Dispose()
[1] The code also works in PowerShell [Core] v7+, but not in PowerShell Core v6.x, because the latter fundamentally did not support WinForms (and WPF).
I want to change the charset in the "http-equiv" content-type tag. Because I'm working with Nokogiri in other parts of my code I'd like to use it for this processing step too.
This is example code:
http_equiv = doc.at('meta[#http-equiv]')
if !http_equiv.nil? && !http_equiv["http-equiv"].nil? && http_equiv["http-equiv"].downcase.eql?("content-type")
http_equiv["content"] = "text/html; charset=utf-8"
end
content = doc.to_html.encode(Encoding::UTF_8)
The problem is that the input content is alway the same as the output content. Nokogiri didn't do anything.
Based on an answer I created a real world example which won't work in contrast to the generated example.
require 'nokogiri'
require 'open-uri'
doc = require 'open-uri'
doc = Nokogiri::HTML(open("http://www.spiegel.de/politik/deutschland/hooligans-gegen-salafisten-demo-in-koeln-eskaliert-a-999401.html"))
content_type = doc.at('meta[#http-equiv="Content-Type"]')
content_type['content'] = 'text/html; charset=UTF-8'
puts doc.to_html
I'd do something like this:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<html>
<head>
<meta http-equiv="content-type" content="text/html">
</head>
<body>
foo
</body>
</html>
EOT
content_type = doc.at('meta[#http-equiv="content-type"]')
content_type['content'] = 'text/html; charset=UTF-8'
puts doc.to_html
Running that outputs:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=US-ASCII">
</head>
<body>
foo
</body>
</html>
You can also do
content_type['content'] << '; charset=UTF-8'
if you're only appending to the existing value.
It doesn't change the content-type.
It changes the content type in the tag, however there is more to it since it seems you don't want to change the content-type marker, you want to change the encoding of the document itself at output. Once you do that, Nokogiri will also change the meta tag to match:
doc.to_html(encoding: 'UTF-8')
will tell Nokogiri to output the HTML, trying to convert from ISO-8859-1 to UTF-8. There is no guarantee that will occur correctly though, because there are some incompatibilities.
Your original attempt using:
content = doc.to_html.encode(Encoding::UTF_8)
won't work correctly, because of HTML encoding that occurs on special characters. You have to change the character encoding before they are HTML-encoded, which should happen if you use to_html(encoding: 'UTF-8').
In an example script that prints HTML, it looks to me that the body tag is not closed. However I have never had experience with Perl before. Is this example incorrect? or is there something else that means body is closed?
print "Content-type: text/html\n\n";
print "<html>\n<head>\n<title>\nPerl CGI
Example\n</title>\n<body>\n<h1>Hello,
World!</h1>\nYour user agent is: <b>\n";
print $cgi_object->user_agent();
print "<b>.</html>\n";
Where there is a . on the last line it looks to me like it should be </body>
You aren't missing anything, that code simply doesn't generate an end tag for the body element, but that tag (unlike the missing Doctype) is optional in HTML anyway so the element will be closed by the browser when it parses the end tag for the html element.
It would be better written something more like this:
#!/usr/bin/env perl
use strict;
use warnings;
use CGI;
use Template;
my $cgi = CGI->new();
print $cgi->header(-charset => 'utf-8');
my $ua = $cgi->user_agent();
my $tt = Template->new();
$tt->process(\*DATA, { ua => $ua });
__END__
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Perl CGI Example</title>
</head>
<body>
<h1>Hello, World!</h1>
<p>Your user agent is: <em>[% ua | html %]</em>.</p>
</body>
</html>
And better still if you ditched CGI and used PSGI/Plack.
This php file appears correct, but is returning an 'unexpected end of file' error. Is the error somewhere in the html file. I have tried putting the tags inside print in "", removed one extra white space on the php line, added white spaces between the brackets[] and quotes'' on the variable lines, and still have the same error when I press enter to send the data to the php script. Here is the html code: http://pastebin.com/Rb62pZcy
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Your Feedback</title>
</head>
<body>
<?php // Script 3.3 handle_form.php
// This page receives the data from feedback.html
// It will receive: title, name, email, comments in $_POST
$title = $_POST [ 'title' ] ;
$name = $_POST [ 'name' ] ;
$email = $_POST [ 'email' ] ;
$comments = $_POST [ 'comments' ] ;
print "<p>Thank you, $title $name, for your comments.</p>"
"<p>You stated that you found this example to be '$response' and added:<br />$comments</p>"
?>
</body>
Instead of this:
print "<p>Thank you, $title $name, for your comments.</p>"
"<p>You stated that you found this example to be '$response' and added:<br />$comments</p>"
Use this:
echo "<p>Thank you, $title $name, for your comments.</p>";
echo "<p>You stated that you found this example to be '$response' and added:<br />$comments</p>";
I think you miss the ";" character.
------------------UPDATE-----------------------------
I try this code and works:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Your Feedback</title>
</head>
<body>
<?php
if (isset($_POST['email'])){
$title = $_POST['title'];
$name = $_POST['name'];
$email = $_POST['email'];
$comments = $_POST['comments'];
}
else
{
$title = "No title arrived";
$name = "No name arrived";
$comments = "No comments arrived";
}
//$response is not defined??
$response = "Live long and prosper";
//so i defined
echo "<p>Thank you, $title $name, for your comments.</p>";
echo "<p>You stated that you found this example to be '$response' and added:<br />$comments</p>";
?>
</body>
</html>
PS: try executing this script alone...name it "handle_form.php" and put this in the nav address bar:
localhost/your_project/handle_form.php
Works on my localhost.....if your problem continue then may be the problem is in the submit page.
Saludos.